2012-12-31 16 views
10

chcę dodać zmienne z dat2:dataframes Merge, różne długości

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

Do 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 

podając następujące dane wyjściowe:

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 

Jak widać informacje z dat1 muszą być replikowane w kilku wierszach w dat2.

To była moja nieudana próba:

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

givng następujący błąd:

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

znajdą replikować przykłady tutaj:

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") 

Odpowiedz

12

Można dodać zmienną dołączenia do dat2 następnie przy użyciu korespondencji seryjnej:

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

Ta odpowiedź współpracuje z przykładowych danych przedstawionych ale zrzuciłby wszystkie niedopasowane wiersze w 'dat1', gdyby były. –

+1

@ G.Grothendieck dobry połów !! trzeba dodać all.x = T. – agstudy

7

nic złego użytkownika @ agstudy odpowiedzi, ale można to zrobić bez powodowania zmian dat2 tworząc anonimowy tymczasowy. Dodanie X jest podobny:

> 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

Spróbuj tego:

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

zakłada to, że jeśli są jakieś wiersze w dat1 że nie mają sobie równych wówczas dat2 kolumny w wyniku powinna być wypełniona NA a jeśli nie są niedopasowane wartości w dat2, a następnie są pomijane. Na przykład:

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

Powyższy znany jest jako lewo dołączyć w SQL i można zrobić tak w sqldf (zignorować ostrzeżenie):

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