web-dev-qa-db-fra.com

cbind 2 images avec un nombre différent de lignes

J'ai deux listes nommées h et g. Elles contiennent chacune 244 images de données et ressemblent à ce qui suit:

h[[1]]
   year  avg    hr   sal
1  2010  0.300  31   2000
2  2011  0.290  30   4000
3  2012  0.275  14    600
4  2013  0.280  24    800 
5  2014  0.295  18   1000
6  2015  0.330  26   7000
7  2016  0.315  40   9000

g[[1]]
   year  pos  fld     
1  2010  A   0.990
2  2011  B   0.995
3  2013  C   0.970
4  2014  B   0.980
5  2015  D   0.990

Je veux cbind ces deux images de données . Mais comme vous le voyez, elles ont un nombre différent de lignes . Je souhaite combiner ces images de manière à ce que les lignes de même année soient combinées dans une seule ligne. Et je veux que les espaces vides soient remplis par NA. Le résultat attendu est le suivant:

   year  avg    hr   sal   pos   fld
1  2010  0.300  31   2000   A   0.990
2  2011  0.290  30   4000   B   0.995
3  2012  0.275  14    600   NA    NA
4  2013  0.280  24    800   C   0.970
5  2014  0.295  18   1000   B   0.980
6  2015  0.330  26   7000   D   0.990
7  2016  0.315  40   9000   NA    NA

De plus, je souhaite répéter cette opération pour les 244 images de chaque liste (h et g..__). J'aimerais créer une nouvelle liste nommée final qui contient les 244 images combinées.

Comment puis-je faire cela ...? Toutes les réponses seront grandement appréciées :)

6
min

Je pense que vous devriez plutôt utiliser merge:

merge(df1, df2, by="year", all = T)

Pour vos données:

df1 = data.frame(matrix(0, 7, 4))
names(df1) = c("year", "avg", "hr", "sal")
df1$year = 2010:2016
df1$avg = c(.3, .29, .275, .280, .295, .33, .315)
df1$hr = c(31, 30, 14, 24, 18, 26, 40)
df1$sal = c(2000, 4000, 600, 800, 1000, 7000, 9000)
df2 = data.frame(matrix(0, 5, 3))
names(df2) = c("year", "pos", "fld")
df2$year = c(2010, 2011, 2013, 2014, 2015)
df2$pos = c('A', 'B', 'C', 'B', 'D')
df2$fld = c(.99,.995,.97,.98,.99)

cbind est destiné à column-bind deux dataframes qui sont compatibles dans tous les sens. Mais ce que vous voulez faire est la valeur réelle merge, où vous souhaitez que les éléments des deux trames de données ne soient pas ignorés, et pour les valeurs manquantes, vous obtenez plutôt NA.

7
A.Yazdiha

Nous pouvons utiliser Map avec cbind.fill (de rowr) à cbind le 'data.frame' correspondant à 'h' et 'g'.

library(rowr)
Map(cbind.fill, h, g, MoreArgs = list(fill=NA))

Mettre à jour

Sur la base des résultats attendus, il semble que le PO voulait une merge au lieu de cbind

f1 <- function(...) merge(..., all = TRUE, by = 'year')
Map(f1, h, g)
#[[1]]
#  year   avg hr  sal  pos   fld
#1 2010 0.300 31 2000    A 0.990
#2 2011 0.290 30 4000    B 0.995
#3 2012 0.275 14  600 <NA>    NA
#4 2013 0.280 24  800    C 0.970
#5 2014 0.295 18 1000    B 0.980
#6 2015 0.330 26 7000    D 0.990
#7 2016 0.315 40 9000 <NA>    NA

Ou, comme l'a mentionné @Colonel Beauvel, cela peut être compact 

Map(merge, h, g, by='year', all=TRUE)

les données

h <- list(structure(list(year = 2010:2016, avg = c(0.3, 0.29, 0.275, 
0.28, 0.295, 0.33, 0.315), hr = c(31L, 30L, 14L, 24L, 18L, 26L, 
 40L), sal = c(2000L, 4000L, 600L, 800L, 1000L, 7000L, 9000L)), .Names = c("year", 
 "avg", "hr", "sal"), class = "data.frame", row.names = c("1", 
 "2", "3", "4", "5", "6", "7")))

g <- list(structure(list(year = c(2010L, 2011L, 2013L, 2014L, 2015L
), pos = c("A", "B", "C", "B", "D"), fld = c(0.99, 0.995, 0.97, 
0.98, 0.99)), .Names = c("year", "pos", "fld"), class = "data.frame",
row.names = c("1", 
"2", "3", "4", "5")))
1
akrun