【问题标题】:Merging odd number of data frames with suffixes合并奇数个带后缀的数据帧
【发布时间】:2020-09-20 02:25:03
【问题描述】:

我正在尝试合并数据框列表,并且在这个社区中遇到了许多不同的答案,例如 R - reduce with merge and more than 2 suffixes (or: how to merge multiple dataframes and keep track of columns) 。但是在解决了这些答案之后,它适用于偶数个数据帧,但不适用于奇数个数据帧。

myDF <- cbind(typecar = rownames(mtcars), mtcars)
rownames(myDF) <- NULL
df1 <- myDF
df2 <-  myDF
df3<- myDF
df4 <- myDF

for(i in head(seq_along(list.df), -1)) {

  res <- merge(res, list.df[[i+1]], all = TRUE, 
               suffixes = sfx[i:(i+1)], by = "typecar")
}

上面的代码对偶数个df按预期工作,如下所示

list.df <- list(df1, df2, df3,df4)
sfx <- c(".df1", ".df2", ".df3", ".df4")

但在尝试奇数时,最后一个 .df3 不会添加为后缀

list.df <- list(df1, df2, df3)
sfx <- c(".df1", ".df2", ".df3")

这里的 colnames 看起来像这样。

 [1] "typecar"  "mpg.df1"  "cyl.df1"  "disp.df1" "hp.df1"   "drat.df1" "wt.df1"   "qsec.df1" "vs.df1"   "am.df1"   "gear.df1" "carb.df1" "mpg.df2" 
[14] "cyl.df2"  "disp.df2" "hp.df2"   "drat.df2" "wt.df2"   "qsec.df2" "vs.df2"   "am.df2"   "gear.df2" "carb.df2" "mpg"      "cyl"      "disp"    
[27] "hp"       "drat"     "wt"       "qsec"     "vs"       "am"       "gear"     "carb"  

我想要的是

 [1] "typecar"  "mpg.df1"  "cyl.df1"  "disp.df1" "hp.df1"   "drat.df1" "wt.df1"   "qsec.df1" "vs.df1"   "am.df1"   "gear.df1" "carb.df1" "mpg.df2" 
[14] "cyl.df2"  "disp.df2" "hp.df2"   "drat.df2" "wt.df2"   "qsec.df2" "vs.df2"   "am.df2"   "gear.df2" "carb.df2" "mpg.df3"      "cyl.df3"      "disp.df3"    
[27] "hp.df3"       "drat.df3"     "wt.df3"       "qsec.df3"     "vs.df3"       "am.df3"       "gear.df3"     "carb.df3"  

尝试使用 dplyr join,但情况相同。遇到了这个https://github.com/tidyverse/dplyr/issues/1296。有什么方法可以处理奇数个数据帧吗?

【问题讨论】:

    标签: r join merge dplyr purrr


    【解决方案1】:

    一个更简单的选择是使用对应的list 名称或对象名称作为后缀命名list 元素列名称,但merge 中用作by 变量的列名称除外。

    list.df <- Map(function(x, nm) {i1 <- names(x) != 'typecar'
                names(x)[i1] <- paste0(names(x)[i1], ".", nm)
                x
        }, list.df, names(list.df))
    

    然后,我们使用Reduce/merge

    out <- Reduce(function(...) merge(..., by = 'typecar', all = TRUE), list.df)
    names(out)
    #[1] "typecar"  "mpg.df1"  "cyl.df1"  "disp.df1" "hp.df1"   "drat.df1" "wt.df1"   "qsec.df1" "vs.df1"   "am.df1"   "gear.df1" "carb.df1"
    #[13] "mpg.df2"  "cyl.df2"  "disp.df2" "hp.df2"   "drat.df2" "wt.df2"   "qsec.df2" "vs.df2"   "am.df2"   "gear.df2" "carb.df2" "mpg.df3" 
    #[25] "cyl.df3"  "disp.df3" "hp.df3"   "drat.df3" "wt.df3"   "qsec.df3" "vs.df3"   "am.df3"   "gear.df3" "carb.df3"
    

    数据

    list.df <- mget(paste0('df', 1:3))
    

    【讨论】:

    • @johnsmith0 是否要删除后缀
    • @johnsmith0 我用Map代替mapply
    • @johnsmith0 `Map(function(x, nm) {i1
    • @johnsmith0 能否请您展示一个可重现的小示例来显示错误
    • @johnsmith0 在这个数据集中,哪个是by 变量。在您展示的示例中,它是“typecar”。所以,如果不是这样的话。你需要改变 `names(x) != 'typecar'
    【解决方案2】:

    你可以使用:

    do.call(rbind,list.df)
    

    【讨论】:

    • 谢谢丹尼尔。但我提到的是连接,而不是行绑定。我更新了问题。
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2020-03-31
    相关资源
    最近更新 更多