2012-12-31 15 views
10

Tôi muốn thêm biến từ dat2:dataframes Merge, độ dài khác nhau

  concreteness familiarity typicality 
amoeba   3.60  1.30  1.71 
bacterium   3.82  3.48  2.13 
leech    5.71  1.83  4.50 

Để dat1:

ID variable value 
1 1 amoeba  0 
2 2 amoeba  0 
3 3 amoeba NA 
251 1 bacterium  0 
252 2 bacterium  0 
253 3 bacterium  0 
501 1  leech  1 
502 2  leech  1 
503 3  leech  0 

Giving đầu ra sau đây:

X ID variable value concreteness familiarity typicality 
1 1 1 amoeba  0   3.60  1.30  1.71 
2 2 2 amoeba  0   3.60  1.30  1.71 
3 3 3 amoeba NA   3.60  1.30  1.71 
4 251 1 bacterium  0   3.82  3.48  2.13 
5 252 2 bacterium  0   3.82  3.48  2.13 
6 253 3 bacterium  0   3.82  3.48  2.13 
7 501 1  leech  1   5.71  1.83  4.50 
8 502 2  leech  1   5.71  1.83  4.50 
9 503 3  leech  0   5.71  1.83  4.50 

Như bạn có thể thấy thông tin từ dat1 phải được sao chép qua nhiều hàng trong dat2.

Đây là thất bại của tôi:

dat3 <- merge(dat1, dat2, by=intersect(dat1$variable(dat1), dat2$row.names(dat2))) 

Givng các lỗi sau:

Error in as.vector(y) : attempt to apply non-function 

Hãy tìm sao chép ví dụ ở đây:

dat1:

structure(list(ID = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), variable = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("amoeba", "bacterium", 
"leech", "centipede", "lizard", "tapeworm", "head lice", "maggot", 
"ant", "moth", "mosquito", "earthworm", "caterpillar", "scorpion", 
"snail", "spider", "grasshopper", "dust mite", "tarantula", "termite", 
"bat", "wasp", "silkworm"), class = "factor"), value = c(0L, 
0L, NA, 0L, 0L, 0L, 1L, 1L, 0L)), .Names = c("ID", "variable", 
"value"), row.names = c(1L, 2L, 3L, 251L, 252L, 253L, 501L, 502L, 
503L), class = "data.frame") 

dat2:

structure(list(concreteness = c(3.6, 3.82, 5.71), familiarity = c(1.3, 
3.48, 1.83), typicality = c(1.71, 2.13, 4.5)), .Names = c("concreteness", 
"familiarity", "typicality"), row.names = c("amoeba", "bacterium", 
"leech"), class = "data.frame") 

Trả lời

12

Bạn có thể thêm một biến tham gia để dat2 sau đó sử dụng kết hợp:

dat2$variable <- rownames(dat2) 
merge(dat1, dat2) 
    variable ID value concreteness familiarity typicality 
1 amoeba 1  0   3.60  1.30  1.71 
2 amoeba 2  0   3.60  1.30  1.71 
3 amoeba 3 NA   3.60  1.30  1.71 
4 bacterium 1  0   3.82  3.48  2.13 
5 bacterium 2  0   3.82  3.48  2.13 
6 bacterium 3  0   3.82  3.48  2.13 
7  leech 1  1   5.71  1.83  4.50 
8  leech 2  1   5.71  1.83  4.50 
9  leech 3  0   5.71  1.83  4.50 
+1

Câu trả lời này làm việc với các dữ liệu mẫu thể hiện nhưng sẽ thả tất cả các hàng chưa khớp trong 'dat1' nếu có bất kỳ hàng nào. –

+1

@ G.Gothendieck bắt tốt !! cần thêm all.x = T. – agstudy

7

Không có gì sai với câu trả lời @ agstudy, nhưng bạn có thể làm điều đó mà không thực sự thay đổi dat2 bằng cách tạo ra một tạm thời vô danh. Thêm X cũng tương tự như:

> merge(cbind(dat1, X=rownames(dat1)), cbind(dat2, variable=rownames(dat2))) 
    variable ID value X concreteness familiarity typicality 
1 amoeba 1  0 1   3.60  1.30  1.71 
2 amoeba 2  0 2   3.60  1.30  1.71 
3 amoeba 3 NA 3   3.60  1.30  1.71 
4 bacterium 1  0 251   3.82  3.48  2.13 
5 bacterium 2  0 252   3.82  3.48  2.13 
6 bacterium 3  0 253   3.82  3.48  2.13 
7  leech 1  1 501   5.71  1.83  4.50 
8  leech 2  1 502   5.71  1.83  4.50 
9  leech 3  0 503   5.71  1.83  4.50 
8

Hãy thử điều này:

merge(dat1, dat2, by.x = 2, by.y = 0, all.x = TRUE) 

này giả định rằng nếu có bất kỳ hàng trong dat1 đó là chưa từng có thì dat2 cột trong kết quả nên được lấp đầy với NA và nếu có là giá trị chưa khớp trong dat2 thì chúng không được chú ý. Ví dụ:

dat2a <- dat2 
rownames(2a)[3] <- "elephant" 
# the above still works: 
merge(dat1, dat2a, by.x = 2, by.y = 0, all.x = TRUE) 

Trên đây được biết đến như một trái tham gia trong SQL và có thể được thực hiện như thế này trong sqldf (bỏ qua các cảnh báo):

library(sqldf) 
sqldf("select * 
     from dat1 left join dat2 
     on dat1.variable = dat2.row_names", 
     row.names = TRUE)