【问题标题】:Join list of dataframes in sequence using full_join in R使用 R 中的 full_join 按顺序连接数据帧列表
【发布时间】:2020-11-12 00:01:15
【问题描述】:

我有一个具有相似变量名的数据框列表,我希望使用 full_join 按照它们在列表中出现的顺序加入这些数据框。

require(tidyverse)

x<-data.frame(id=c("a","a","b","b","b","c","c","c","c"),
              sub.id=c("1","2","1","2","3","1","2","3","4"))

y<-data.frame(id = as.character(rep(1:4,each=2)),
              sub.id = c("AA","CC","DD","AA","GG","OO","PP","OW"))

z<-data.frame(id = c("AA","CC","DD","GG","OO","OW","PP"),
              sub.id = as.character(1:7))

dfs<-list(x,y,z)

我尝试使用 purrr 包中的 reduce 但这会将列表中的所有数据帧连接到第一个数据帧。在这种情况下,x 数据帧。

dfs %>% 
  reduce(full_join,by = c("sub.id" = "id"))

有没有办法对列表中的数据帧执行full_join,以使by 遵循数据帧出现在列表中的顺序?在此示例中,xsub.id 将与 yid 匹配,然后加入后来自 ysub.id 将匹配最终加入的 zid

编辑: 这样做的预期结果应该类似于以下内容:

    id sub.id.x sub.id.y sub.id.y.y
1   a        1       AA          1
2   a        1       CC          2
3   a        2       DD          3
4   a        2       AA          1
5   b        1       AA          1
6   b        1       CC          2
7   b        2       DD          3
8   b        2       AA          1
9   b        3       GG          4
10  b        3       OO          5
11  c        1       AA          1
12  c        1       CC          2
13  c        2       DD          3
14  c        2       AA          1
15  c        3       GG          4
16  c        3       OO          5
17  c        4       PP          7
18  c        4       OW          6

此时连接的列名后缀不变。

【问题讨论】:

  • 当您的意思是对 x 和 y 进行完全连接时。结果中出现的 sub_id 不是 y 的 sub_id,而是来自两者。那么你到底想要什么?你能发布你的预期结果吗?

标签: r dataframe dplyr purrr


【解决方案1】:

也许,我们需要一个for 循环来在每次连接生成的输出后更改列名

out <- dfs[[1]]
for(i in 2:length(dfs)) {
    out <- full_join(out, dfs[[i]], by = c('sub.id' = 'id'))
    names(out)[names(out) == 'sub.id'] <- paste0("sub.id", i)
    names(out)[names(out) == 'sub.id.y'] <- 'sub.id'
  }

-输出

out
#   id sub.id2 sub.id3 sub.id
#1   a       1      AA      1
#2   a       1      CC      2
#3   a       2      DD      3
#4   a       2      AA      1
#5   b       1      AA      1
#6   b       1      CC      2
#7   b       2      DD      3
#8   b       2      AA      1
#9   b       3      GG      4
#10  b       3      OO      5
#11  c       1      AA      1
#12  c       1      CC      2
#13  c       2      DD      3
#14  c       2      AA      1
#15  c       3      GG      4
#16  c       3      OO      5
#17  c       4      PP      7
#18  c       4      OW      6

【讨论】:

    【解决方案2】:

    如果我们可以假设连接列始终位于第一个数据帧的末尾,而第一个数据帧位于第二个数据帧的末尾,那么您可以这样做:

    在基础 R 中:

    Reduce(function(x,y) merge(x,y,by.x = tail(names(x),1), by.y = names(y)[1], all = TRUE), dfs)
    
       sub.id1 sub.id0 id sub.id11
    1       AA       1  a        1
    2       AA       2  a        1
    3       AA       1  c        1
    4       AA       2  b        1
    5       AA       1  b        1
    6       AA       2  c        1
    7       CC       1  a        2
    8       CC       1  b        2
    9       CC       1  c        2
    10      DD       2  b        3
    11      DD       2  a        3
    12      DD       2  c        3
    13      GG       3  b        4
    14      GG       3  c        4
    15      OO       3  b        5
    16      OO       3  c        5
    17      OW       4  c        6
    18      PP       4  c        7
    

    【讨论】:

      猜你喜欢
      • 2014-10-24
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2020-01-04
      • 1970-01-01
      • 2019-12-11
      相关资源
      最近更新 更多