2011-05-11 16 views
47

Tengo dos data.frames, uno con solo caracteres y el otro con caracteres y valores.Fusionar marcos de datos desiguales y reemplazar las filas que faltan con 0

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e')) 
df2 = data.frame(x=c('a', 'b', 'c'),y = c(0,1,0)) 
merge(df1, df2) 
    x y 
1 a 0 
2 b 1 
3 c 0 

Quiero unir df1 y df2. Los caracteres a, b y c se fusionaron bien y también tienen 0, 1, 0 pero d y e no tienen nada. Quiero d y e también en la tabla de fusión, con la condición 0 0. Así, para cada fila que faltan en el hoja.de.datos gl2, el 0 se debe colocar en la mesa de DF1, como:

x y 
1 a 0 
2 b 1 
3 c 0 
4 d 0 
5 e 0 

Respuesta

72

Tome un vistazo a la página de ayuda para la fusión. El parámetro all le permite especificar diferentes tipos de fusiones. Aquí queremos establecer all = TRUE. Esto hará que la fusión de retorno NA para los valores que no coinciden, que podemos actualizar a 0 con is.na():

zz <- merge(df1, df2, all = TRUE) 
zz[is.na(zz)] <- 0 

> zz 
    x y 
1 a 0 
2 b 1 
3 c 0 
4 d 0 
5 e 0 
+0

Hola Chase, gracias por su solución! ¡Me ayuda! – Lisann

+3

Hunh: he estado usando R desde hace un año y no sabía que podría abordar cada celda en un marco de datos como este. A veces vale la pena cuestionar tus suposiciones. Gracias Chase! – steamer25

+0

Hola Chase, ¿puedo usar el comando "all = true" para df1 solamente? A veces, este comando incluye datos que no están disponibles en df1 pero están disponibles en df2 – jbest

7

O, como alternativa a @ código de Chase, ser un fan reciente plyr con un fondo de bases de datos:

require(plyr) 
zz<-join(df1, df2, type="left") 
zz[is.na(zz)] <- 0 
2

Otra alternativa con data.table.

EJEMPLO DE DATOS

dt1 <- data.table(df1) 
dt2 <- data.table(df2) 
setkey(dt1,x) 
setkey(dt2,x) 

CÓDIGO

dt2[dt1,list(y=ifelse(is.na(y),0,y))] 
+0

En la versión 1.10.4, no necesita 'setkey' y puede usar' df2 [df1, on = "x"] [is.na (y), y : = 0] 'inmediatamente después de crear data.tables para producir el resultado deseado. – lmo

2

utilicé la respuesta dada por el Chase (11 de mayo de respondí '11 a las 14:21), pero he añadido un poco de código para aplicar esa solución a mi problema particular.

Tenía un marco de tasas (usuario, descarga) y un marco de totales (usuario, descarga) para ser fusionado por el usuario, y quería incluir todas las tasas, incluso si no hubiera un total correspondiente. Sin embargo, no podría haber totales faltantes, en cuyo caso la selección de filas para el reemplazo de NA por cero fallaría.

La primera línea de código fusiona. Las siguientes dos líneas cambian los nombres de las columnas en el marco combinado. La instrucción if reemplaza NA por cero, pero solo si hay filas con NA.

# merge rates and totals, replacing absent totals by zero 
graphdata <- merge(rates, totals, by=c("user"),all.x=T) 
colnames(graphdata)[colnames(graphdata)=="download.x"] = "download.rate" 
colnames(graphdata)[colnames(graphdata)=="download.y"] = "download.total" 
if(any(is.na(graphdata$download.total))) { 
    graphdata[is.na(graphdata$download.total),]$download.total <- 0 
} 
Cuestiones relacionadas