J'ai une liste contenant des trames de données comme éléments dans R.
Exemple:
df1 <- data.frame("names"=c("John","Sam","Dave"),"age"=c(21,22,25))
df2 <- data.frame("names"=c("John","Sam"),"score"=c(22,25))
df3 <- data.frame("names"=c("John","Sam","Dave"),"country"=c("US","SA","NZ"))
mylist <- list(df1,df2,df3)
Est-il possible de fusionner tous les éléments de mylist sans utiliser de boucle?
Ma sortie souhaitée pour cet exemple est:
names age score country
1 John 21 22 US
2 Sam 22 25 SA
La liste dans cet exemple n'a que trois éléments; Cependant, je recherche une solution capable de gérer un nombre arbitraire d'éléments.
Vous pouvez utiliser Reduce
, une solution de liner:
Reduce(merge,mylist)
names age score country
1 John 21 22 US
2 Sam 22 25 SA
Exemple rapide et sale:
merge(merge(df1, df2),df3)
EDIT- Question très similaire ici: Fusion simultanée de plusieurs data.frames dans une liste
solution:
merged.data.frame = Reduce(function(...) merge(..., all=F), my.list)
Clause de non-responsabilité - La réponse de @Charles n’a changé que dans le sens de faire merge(..., all=F)
plutôt que T
- de cette façon, cela donne le résultat souhaité.
Juste pour montrer que cela pourrait être fait d'une autre manière ...
mymerge <- function(mylist) {
names(mylist) <- sapply(mylist, function(x) names(x)[2])
ns <- unique(unlist(lapply(mylist, function(x) levels(x$names))))
as.data.frame(c(list(names=ns), lapply(mylist, function(x)
{x[match(ns, x$names),2]})))
}
> mymerge(mylist)
names age score country
1 Dave 25 NA NZ
2 John 21 22 US
3 Sam 22 25 SA
On pourrait facilement s’adapter pour supprimer des lignes avec des valeurs manquantes, ou peut-être simplement supprimer après avec complete.cases
.
Pour montrer que c'est plus rapide, nous allons constituer un plus grand ensemble de données; 100 variables et 25 noms.
set.seed(5)
vs <- paste0("V", 1:100)
mylist <- lapply(vs, function(v) {
x <- data.frame(names=LETTERS[1:25], round(runif(25, 0,100)))
names(x)[2] <- v
x
})
> microbenchmark(Reduce(merge, mylist), myf(mylist))
Unit: milliseconds
expr min lq median uq max
1 myf(mylist) 12.81371 13.19746 13.36571 14.40093 33.90468
2 Reduce(merge, mylist) 199.23714 206.28608 207.30247 208.44939 226.05980
Avez-vous essayé cette fonction?
http://rss.acs.unt.edu/Rdoc/library/gtools/html/smartbind.html
library(gtools)
df1 <- data.frame(list(A=1:10), B=LETTERS[1:10], C=rnorm(10) )
df2 <- data.frame(A=11:20, D=rnorm(10), E=letters[1:10] )
df3 <- df1
out <- smartbind( mylist <- list(df1,df2,df3))