R: Как связать фрейм данных в списке по именам совпадений столбцов? или частичным левым соединением?

моя проблема:

У меня есть список с 8 фреймами данных с разными именами столбцов и похожими именами, поэтому я хочу связать эти фреймы данных по совпадению столбцов. Например, в этом случае

Мне нужно выровнять строки столбцов Yd; Yc; Yb; Ya.

myList<-list(
  data.frame(Ya=sample(letters[1:3]),ZYa=sample(1:3),BYa=sample(1:3)),
  data.frame(Yb=sample(letters[1:2]),ZYb=sample(1:2),BYb=sample(1:2)),
  data.frame(Yc=sample(letters[1:4]),ZYc=sample(1:4),BYc=sample(1:4)),
  data.frame(Yd=sample(letters[1:5]),ZYd=sample(1:5),BYd=sample(1:5)))



myList


[[1]]
  Ya ZYa BYa
1  b   3   1
2  a   2   2
3  c   1   3

[[2]]
  Yb ZYb BYb
1  b   2   2
2  a   1   1

[[3]]
  Yc ZYc BYc
1  c   2   2
2  b   3   4
3  d   4   3
4  a   1   1

[[4]]
  Yd ZYd BYd
1  e   5   2
2  d   1   5
3  a   2   4
4  b   3   1
5  c   4   3

Мой ближайший подход был:

library(tidyverse)
library(gdata) #Including cbindX function

myDataFrame<-mylist %>%
  do.call(cbindX,.) 

поэтому у меня есть такой фрейм данных:

    Ya ZYa BYa   Yb ZYb BYb   Yc ZYc BYc Yd ZYd BYd
1    b   3   1    b   2   2    c   2   2  e   5   2
2    a   2   2    a   1   1    b   3   4  d   1   5
3    c   1   3   NA  NA  NA    d   4   3  a   2   4
4    NA  NA  NA  NA  NA  NA    a   1   1  b   3   1
5    NA  NA  NA  NA  NA  NA   NA  NA  NA  c   4   3

Но мне нужно что-то вроде этого:

    Ya ZYa BYa   Yb ZYb BYb   Yc ZYc BYc Yd ZYd BYd
1    b   3   1    b   2   2    b   3   4  b   3   1
2    a   2   2    a   1   1    a   1   1  a   2   4
3    c   1   3   NA  NA  NA    c   2   2  c   4   3
4   NA  NA  NA   NA  NA  NA    d   4   3  d   1   5
5   NA  NA  NA   NA  NA  NA   NA  NA  NA  e   4   3

Не могли бы вы мне помочь? Спасибо!


person Bryan Castillo    schedule 19.11.2020    source источник


Ответы (2)


Может быть, что-то довольно грубое, сначала получите все rownames:

rnames = Reduce(union,lapply(myList,"[[",1))

Затем cbind в списке, который соответствует этим именам:

do.call(cbind,lapply(myList,function(i)i[match(rnames,i[,1]),]))

       Ya ZYa BYa   Yb ZYb BYb   Yc ZYc BYc Yd ZYd BYd
1       a   3   1    a   2   2    a   4   2  a   4   5
2       c   1   3 <NA>  NA  NA    c   3   4  c   2   1
3       b   2   2    b   1   1    b   1   1  b   1   4
NA   <NA>  NA  NA <NA>  NA  NA    d   2   3  d   3   2
NA.1 <NA>  NA  NA <NA>  NA  NA <NA>  NA  NA  e   5   3

Если вы знаете порядок, то вы его определяете:

rnames = c("b","a","c","d","e")
do.call(cbind,lapply(myList,function(i)i[match(rnames,i[,1]),]))

       Ya ZYa BYa   Yb ZYb BYb   Yc ZYc BYc Yd ZYd BYd
3       b   2   2    b   1   1    b   1   1  b   1   4
1       a   3   1    a   2   2    a   4   2  a   4   5
2       c   1   3 <NA>  NA  NA    c   3   4  c   2   1
NA   <NA>  NA  NA <NA>  NA  NA    d   2   3  d   3   2
NA.1 <NA>  NA  NA <NA>  NA  NA <NA>  NA  NA  e   5   3
person StupidWolf    schedule 19.11.2020
comment
но в этом примере строки не упорядочены по столбцам строки соответствия :( - person Bryan Castillo; 19.11.2020
comment
какие строки соответствия? ой можешь перефразировать свой вопрос. это не rownames! - person StupidWolf; 19.11.2020
comment
Ты прав; Прошу прощения, я думаю, что теперь все правильно. - person Bryan Castillo; 20.11.2020

Мы можем использовать cbind.fill из rowr

library(rowr)
do.call(cbind.fill, c(myList, fill = NA))
person akrun    schedule 19.11.2020
comment
эта работа похожа на cbindX, не выравнивайте строки столбцов, как множественное левое соединение, это то, что мне нужно - person Bryan Castillo; 20.11.2020