Fusionar marcos de datos de diferentes tamaños

Tengo dos marcos de datos d1 y d2 respectivamente, como:

 xyz 10 10 7 10 12 6 11 10 8 11 12 2 12 10 1 12 12 5 xyz 10 10 100 11 10 200 12 12 400 

Quiero algo como:

 xyz 10 10 100 10 12 6 11 10 200 11 12 2 12 10 1 12 12 400 

Realmente lo siento por la pregunta trivial, no pude obtener la respuesta.

Según su descripción, entiendo que desea reemplazar los valores de z en d1 con los valores de z en d2 cuando x & y coincidan.

Usando la base R:

 d3 < - merge(d1, d2, by = c("x","y"), all.x = TRUE) d3[is.na(d3$zy),"zy"] <- d3[is.na(d3$zy),"zx"] d3 <- d3[,-3] names(d3)[3] <- "z" 

lo que da:

 > d3 xyz 1 10 10 100 2 10 12 6 3 11 10 200 4 11 12 2 5 12 10 1 6 12 12 400 

Usando el paquete data.table :

 library(data.table) setDT(d1) # convert the data.frame to a data.table setDT(d2) # idem # join the two data.table's and replace the values d1[d2, on = .(x, y), z := iz] 

o de una vez:

 setDT(d1)[setDT(d2), on = .(x, y), z := iz] 

lo que da:

 > d1 xyz 1: 10 10 100 2: 10 12 6 3: 11 10 200 4: 11 12 2 5: 12 10 1 6: 12 12 400 

Usando el paquete dplyr :

 d3 < - left_join(d1, d2, by = c("x","y")) %>% mutate(zy = ifelse(is.na(zy), zx, zy)) %>% select(-zx) %>% rename(z = zy) 

Además de la excelente @Jaap answer wrt data.table

En data.table, puedes unirte usando las teclas, y con data.table todo lo que se haga usando las teclas es la opción más rápida. Incluso podría tener diferentes nombres de columna, consulte el ejemplo modificado a continuación.

A lo largo de las líneas, datos:

 xyz 10 10 100 11 10 200 12 12 400 xqz 10 10 7 10 12 6 11 10 8 11 12 2 12 10 1 12 12 5 

y código:

 library(data.table) d1 < - fread("d1.csv", sep=" ") d2 <- fread("d2.csv", sep=" ") # here is data.table keys magic # note different column names setkey(d1, x, q) setkey(d2, x, y) q <- d2[d1][is.na(z), z := iz][, iz := NULL] print(q) 

resultado:

  xyz 1: 10 10 100 2: 10 12 6 3: 11 10 200 4: 11 12 2 5: 12 10 1 6: 12 12 400 

Parece que desea asegurarse de que solo haya un valor z para cada valor y . La pregunta principal es cómo elegir qué valor z asociar con él. Según la descripción, supongo que desea que el segundo dataframe anule siempre, o desea que se tome el valor máximo.

Comience con los datos sin procesar:

 df1 < - structure(list(x = c(10L, 10L, 11L, 11L, 12L, 12L), y = c(10L, 12L, 10L, 12L, 10L, 12L), z = c(7L, 6L, 8L, 2L, 1L, 5L)), .Names = c("x", "y", "z"), class = "data.frame", row.names = c(NA, -6L)) df2 <- structure(list(x = 10:12, y = c(10L, 10L, 12L), z = c(100L, 200L,400L)), .Names = c("x", "y", "z"), class = "data.frame", row.names = c(NA,-3L)) 

Si es el máximo que desea, entonces probablemente quiera simplemente combinar los dos cuadros, y luego extraer el máximo para cada x y y :

 merged.df < - aggregate(z ~ x + y, data = rbind(df1, df2), max) 

Si, en cambio, desea que el segundo dataframe anule al primero, entonces agregará usando el último valor para coincidir

 merged.df < - aggregate(z ~ x+ y, data=rbind(df1, df2), function(d) tail(d, n=1)) 

Si tiene muchas columnas además de z , entonces solo puedo suponer que desea el último comportamiento. Para esto, es mejor usar una biblioteca como data.table o dplyr . En dplyr , se vería así

 require(dplyr) merged.df < - rbind(df1, df2) %>% group_by(x, y) %>% summarise_each(funs(last)) 

Con data.table se vería como

 require(data.table) merged.df < - setDT(rbind(df1, df2))[, lapply(.SD, last), .(x,y)]