web-dev-qa-db-ja.com

行数が異なる2つのデータフレームをバインドします

hgという名前の2つのリストがあります。それぞれ244のデータフレームが含まれ、次のようになります。

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

これら2つのデータフレームをcbindしたいです。しかし、ご覧のとおり、行の数は異なります。同じ年の行が1つの行に結合されるように、これらのデータフレームを結合したいと思います。そして、空のスペースをNAで埋めたい。結果は次のようになります。

   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

また、hgの各リスト内の244個のデータフレームすべてに対してこれを繰り返したいと思います。 244個の結合されたデータフレームを含むfinalという名前の新しいリストを作成したいと思います。

これどうやってするの...?すべての回答は大歓迎です:)

10
min

代わりにmergeを使用する必要があると思います:

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

データについて:

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)

cbindcolumn-bind 2つのdataframesは、あらゆる意味で互換性があります。しかし、目的は実際のmergeであり、2つのデータフレームの要素を破棄しないようにし、欠損値の場合は代わりにNAを取得します。

13
A.Yazdiha

Mapcbind.fillrowrから)とともに使用して、 'h'および 'g'からの対応する 'data.frame'をcbindにできます。

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

更新

予想される出力に基づいて、OPはmergeではなく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

または@Colonel Beauvelが述べたように、これはコンパクトにすることができます

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

データ

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")))
2
akrun

tidyverseツールを使用してこれを行う方法は次のとおりです。

library(tidyverse)

h <- list()
g <- list()

h[[1]] <- tribble(
  ~year,  ~avg, ~hr,  ~sal,
  2010,  0.300,  31,  2000,
  2011,  0.290,  30,  4000,
  2012,  0.275,  14,   600,
  2013,  0.280,  24,   800,
  2014,  0.295,  18,  1000,
  2015,  0.330,  26,  7000,
  2016,  0.315,  40,  9000
)

g[[1]] <- tribble(
  ~year,  ~pos,  ~fld,
   2010,   "A",   0.990,
   2011,   "B",   0.995,
   2013,   "C",   0.970,
   2014,   "B",   0.980,
   2015,   "D",   0.990
)

map2(h, g, left_join)

生成するもの:

[[1]]
# A tibble: 7 x 6
   year   avg    hr   sal pos      fld
  <dbl> <dbl> <dbl> <dbl> <chr>  <dbl>
1  2010 0.3      31  2000 A      0.99 
2  2011 0.290    30  4000 B      0.995
3  2012 0.275    14   600 NA    NA    
4  2013 0.28     24   800 C      0.97 
5  2014 0.295    18  1000 B      0.98 
6  2015 0.33     26  7000 D      0.99 
7  2016 0.315    40  9000 NA    NA  
1
Sean Kross