2012-01-05 31 views
5

Tôi có một vấn đề khi kết hợp các vectơ sau đây có trong danh sách:làm thế nào để kết hợp vectơ với độ dài khác nhau trong một danh sách trong R?

x <- list(as.numeric(c(1,4)),as.numeric(c(3,19,11))) 
names (x[[1]]) <- c("species.A","species.C") 
names (x[[2]]) <- c("species.A","species.B","species.C") 

mang đến cho các danh sách sau:

 
>x 
>[[1]] 
>species.A species.C 
>   1   4 
>[[2]] 
>species.A species.B species.C 
>  3  19  11 

kết hợp chúng bằng cách sử dụng chức năng do.call: y<- do.call(cbind,x)

cung cấp:

 
>y 
>    [,1] [,2] 
> species.A 1 3 
> species.B 4 19 
> species.C 1 11 

trong khi tôi muốn có được điều này:

 
>    [,1] [,2] 
> species.A 1 3 
> species.B NA 19 
> species.C 4 11 

Trả lời

4

Bạn cần phải cung cấp cho R giúp đỡ hơn một chút, bằng cách đầu tiên chuẩn bị các vectơ đặc biệt, tất cả đều cùng độ dài, mà cuối cùng bạn muốn cbind với nhau. Nếu không (như bạn đã thấy) R sử dụng các quy tắc tái chế thông thường của nó để điền vào ma trận.

Hãy thử một cái gì đó như thế này:

spp <- paste("species", c("A", "B", "C"), sep=".") 

x2 <- lapply(x, FUN=function(X) X[spp]) 
mat <- do.call("cbind", x2) 
row.names(mat) <- spp 

mat 
      [,1] [,2] 
species.A 1 3 
species.B NA 19 
species.C 4 11 

EDIT: Như Brian đề cập trong các ý kiến, điều này có thể được thực hiện một chút nhỏ gọn hơn (nhưng tại các chi phí của một số khả năng đọc). Cái nào bạn sử dụng chỉ là vấn đề về hương vị:

mat <- do.call("cbind", lapply(x, "[", spp)) 
row.names(mat) <- spp 
+0

Could in-line phân x2, và đơn giản hóa nó như là 'do.call (cbind, lapply (x, '[', spp))' –

+0

Tôi đã phá vỡ nhiệm vụ, và làm cho định nghĩa FUN rõ ràng hơn vì mục đích rõ ràng, vì tôi nghĩ công bằng để kết luận rằng OP là một người mới tương đối. Nhưng có, tất cả điều này có thể được thực hiện trong một dòng duy nhất. Trong thực tế, tôi cũng có thể thêm rằng như là một chỉnh sửa nhanh chóng. Cảm ơn. –

+0

Khá hợp lý; Tôi chỉ đang chỉ ra một giải pháp thay thế. –

5

Có vẻ như bạn đang thực sự cố gắng hợp nhất. Như vậy, merge sẽ hoạt động. Bạn chỉ cần nói với nó để hợp nhất trên tên, và để giữ tất cả các hàng.

do.call(merge, c(x, by=0, all=TRUE)) # by=0 and by="row.names" are the same 

(Điều này sẽ tạo ra một khung dữ liệu chứ không phải là một ma trận, nhưng đối với hầu hết các mục đích không phải là một vấn đề.)

1
merge(x = x[[1]], y = x[[2]], by = "names", all.y = TRUE) 
+1

Xin chào và chào mừng bạn đến với SO. Đó là một thực tế tuyệt vời để thêm một chút giải thích để chỉ viết câu trả lời. – Fluffeh

Các vấn đề liên quan