【问题标题】:Using Reduce to merge multiple data frames with passing arguments and without defining function outside the Reduce (syntax)使用 Reduce 合并多个带有传递参数的数据帧,而不在 Reduce(语法)之外定义函数
【发布时间】:2016-01-22 19:52:09
【问题描述】:

我有一个列表,其中包含与下面生成的对象相对应的多个数据集:

data("AirPassengers"); data("mtcars")
lstDta <- list(dtaCars1 = mtcars, dtaCars2 = mtcars,
               dtaCars3 = mtcars, dtaOtherStuff = AirPassengers)

我想合并 row.names

上的 cars 数据集

结果

结果应该对应数据框:

res <- merge(
    x = merge(x = lstDta$dtaCars1, y = lstDta$dtaCars2, by = "row.names"),
    y = lstDta$dtaCars3, by.y = "row.names",
    by.x = "Row.names")

使用row.names 连接列的位置(理想情况下,我会删除Row.names 变量,但这不会打扰我)

> dim(res)
[1] 32 34 

问题

我想使用Reduce 获得相同的结果,我特别感兴趣:

  • 合并row.names 上的数据帧
  • 过滤列表。例如,我只想合并 cars 数据而忽略 other 数据集

附加要求

Very useful answer 建议在代码行之外定义一个函数:

merge.all <- function(x, y) {
    merge(x, y, all=TRUE, by="Sample")
}

output <- Reduce(merge.all, DataList)

我想避免在Reduce 语法之外定义函数。

尝试

如下图所示,我想把所有东西都塞进Reduce

dtaMrgd <- Reduce(f = function(x,y) {merge(x,y, by = "row.names")},
              lapply(lstDta[grepl("Cars", names(lstDta)) == TRUE]))

所以Reduce 做了两件事:

  1. 根据匹配的名称使用字符串过滤传递的列表
  2. 使用过滤后的对象应用具有所需特征的合并功能

针话说,上面的代码失败了。


注意事项

我对 res &lt;- Reduce( ... ) 格式的解决方案特别感兴趣。我对在Reduce() 之外创建一些额外的对象/函数不感兴趣。

【问题讨论】:

    标签: r function merge dataframe


    【解决方案1】:

    我认为这是实现您想要的一种方法:

    res2 <- Reduce(function(x, y) {
      data.frame(merge(x, y, by = 0), row.names = row.names(x))[,-1]
    }, lstDta[grep("Cars", names(lstDta))])
    
    dim(res2)
    #[1] 32 33
    
    names(res2)
    #[1] "mpg.x"  "cyl.x"  "disp.x" "hp.x"   "drat.x" "wt.x"   "qsec.x" "vs.x"   "am.x"   "gear.x" "carb.x"
    #[12] "mpg.y"  "cyl.y"  "disp.y" "hp.y"   "drat.y" "wt.y"   "qsec.y" "vs.y"   "am.y"   "gear.y" "carb.y"
    #[23] "mpg"    "cyl"    "disp"   "hp"     "drat"   "wt"     "qsec"   "vs"     "am"     "gear"   "carb"
    

    • 为了过滤输入列表,我使用lstDta[grep("Cars", names(lstDta))]
    • 我将每个合并结果的第一列 (Row.names) 删除为 [,-1]
    • 您可以使用by = 0 作为row.names 的同义词,以避免在尝试合并Row.namesrow.names 时出现任何问题
    • 如果没有显式的data.frame(..., row.names = row.names(x)),合并将删除原始的mtcars 行名,并用默认的1:nrow(x) 替换它们。这对于随后的合并调用会产生问题。

    来自帮助文件?merge

    可以通过名称、编号或逻辑来指定要合并的列 向量:名称“row.names”或数字 0 指定行名称。 如果按名称指定,它必须唯一对应于 输入。

    【讨论】:

    • 它看起来像一个魅力,你能解释一下你为什么这样做吗:data.frame(merge(x, y, by = 0)
    猜你喜欢
    • 2021-08-11
    • 2014-11-10
    • 2012-09-05
    • 1970-01-01
    • 2013-11-04
    • 2020-03-26
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    相关资源
    最近更新 更多