español - Fusionando más de 2 dataframes en R por rownames
ejemplos de data.frame en r (4)
Recopilo datos de 4 df y me gustaría fusionarlos por rownames. Estoy buscando una manera eficiente de hacer esto. Esta es una versión simplificada de los datos que tengo.
df1 <- data.frame(N= sample(seq(9, 27, 0.5), 40, replace= T),
P= sample(seq(0.3, 4, 0.1), 40, replace= T),
C= sample(seq(400, 500, 1), 40, replace= T))
df2 <- data.frame(origin= sample(c("A", "B", "C", "D", "E"), 40,
replace= T),
foo1= sample(c(T, F), 40, replace= T),
X= sample(seq(145600, 148300, 100), 40, replace= T),
Y= sample(seq(349800, 398600, 100), 40, replace= T))
df3 <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100)
df4 <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100)
rownames(df1) <- paste("P", sprintf("%02d", c(1:40)), sep= "")
rownames(df2) <- rownames(df1)
rownames(df3) <- rownames(df1)
rownames(df4) <- rownames(df1)
Esto es lo que normalmente haría:
# merge df1 and df2
dat <- merge(df1, df2, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
# merge dat and df3
dat <- merge(dat, df3, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
# merge dat and df4
dat <- merge(dat, df4, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
Como puede ver, esto requiere mucho código. Mi pregunta es si el mismo resultado se puede lograr con medios más simples. Lo intenté (sin éxito): ACTUALIZAR: ¡esto funciona ahora!
MyMerge <- function(x, y){
df <- merge(x, y, by= "row.names", all.x= F, all.y= F)
rownames(df) <- df$Row.names
df$Row.names <- NULL
return(df)
}
dat <- Reduce(MyMerge, list(df1, df2, df3, df4))
Gracias de antemano por cualquier sugerencia
Al editar su función, se me ocurrió la función que le permite combinar más marcos de datos con una clave de columna específica (nombre de la columna). El marco de datos resultante incluye todas las variables de los marcos de datos fusionados (si desea mantener solo las variables comunes (excluyendo NA, use: all.x= FALSE, all.y= FALSE
)
MyMerge <- function(x, y){
df <- merge(x, y, by= "name of the common column", all.x= TRUE, all.y= TRUE)
return(df)
}
new.df <- Reduce(MyMerge, list(df1, df2, df3, df4))
He estado buscando la misma función. Después de probar algunas de las opciones aquí y otras en otros lugares. Lo más fácil para mí fue:
cbind.data.frame (df1, df2, df3, df4 ....)
Tres líneas de código le darán exactamente el mismo resultado:
dat2 <- cbind(df1, df2, df3, df4)
colnames(dat2)[-(1:7)] <- paste(paste(''V'', rep(1:100, 2),sep = ''''),
rep(c(''x'', ''y''), each = 100), sep = c(''.''))
all.equal(dat,dat2)
Ah, ya veo, ahora entiendo por qué estás metido en tanto dolor. Usar el viejo bucle for
seguramente hace el truco. Tal vez hay soluciones incluso más inteligentes
rn <- rownames(df1)
l <- list(df1, df2, df3, df4)
dat <- l[[1]]
for(i in 2:length(l)) {
dat <- merge(dat, l[[i]], by= "row.names", all.x= F, all.y= F) [,-1]
rownames(dat) <- rn
}
join_all
from plyr
probablemente haga lo que quieras. Pero todos deben ser marcos de datos y los nombres de fila se agregan como una columna
require(plyr)
df3 <- data.frame(df3)
df4 <- data.frame(df4)
df1$rn <- rownames(df1)
df2$rn <- rownames(df2)
df3$rn <- rownames(df3)
df4$rn <- rownames(df4)
df <- join_all(list(df1,df2,df3,df4), by = ''rn'', type = ''full'')
type
argumento type
debería ayudar incluso si los nombres de las filas varían y no coinciden. Si no desea los nombres de los renglones:
df$rn <- NULL