【问题标题】:R - Reduce function used for merging returns a list instead of a dataframeR - 用于合并的 Reduce 函数返回列表而不是数据框
【发布时间】:2019-01-14 18:03:24
【问题描述】:

我正在尝试根据名称合并多个数据框。

我的数据框被命名 集群_1_N1、集群_1_N2、集群_1_N3 集群_2_N1、集群_2_N2、集群_2_N3 等等 3, 4 ...它们都包含两列。

> Cluster_1_N1
ID   counts_N1
1       405
2         6
3       201
4        40

> Cluster_1_N2
ID   counts_N2
1       657
2         9
3       250
4        77

合并将在“ID”列上完成。我想获取多个数据帧,分别命名为“Cluster_1”、“Cluster_2”...结构如下

>Cluster_1
ID counts_N1 counts_N2    counts_N3
1       405         657    10
2         6         9      50
3       201        250     55
4        40         77     68

>Cluster_2
ID counts_N1 counts_N2  counts_N3
1      1        652        11
2      7         3         52
3      58        2         56
4      46        7         68

我试过这个:

for(i in 1:2) {
z <- paste ("C", i, sep = "")
n <- paste("Cluster_", i, sep = "")

assign (n, Reduce(function(...) merge (..., by="ID", all= T)),
              list(mget(ls(pattern=z)))))
                                          }    

此代码返回“Cluster_1”和“Cluster_2”对象,但这些对象是列表(包含要合并在一起的适当数据帧)而不是数据帧!因此,Reduce 函数正确列出了我要合并的所有“cluster_1”和“cluster_2”数据帧,但没有将它们合并...

我的错误在哪里? (我希望我足够清楚,这是我的第一篇文章......)

【问题讨论】:

  • 您最初提供Cluster_1_N1,但您的mget 正在寻找C1。如果你使用z &lt;- sprintf("Cluster_%s_*", i) 会怎样?顺便说一句:处理像这样结构相同的数据帧很容易很麻烦,我敦促你考虑处理lists of dataframes
  • 只是为了更好地理解这一点,这是否是函数的一部分,您不知道数据帧的名称,因此使用mget?看起来您在每个单独的数据框上调用Reduce,而不是在它们的列表上,因为您在循环内执行Reduce

标签: r list dataframe merge reduce


【解决方案1】:

这是基地R中的一种方式:

pattern  <- "Cluster_(\\d+)_N\\d+"
dfs_all  <- mget(ls(pattern=pattern))
df_split <- split(dfs_all,gsub(pattern, "\\1", names(dfs_all))) 
lapply(df_split, Reduce, f = merge)

# $`1`
#   ID counts_N1 counts_N2
# 1  1       405       657
# 2  2         6         9
# 3  3       201       250
# 4  4        40        77
# 
# $`2`
#   ID counts_N1 counts_N2
# 1  1         1       652
# 2  2         7         3
# 3  3        58         2
# 4  4        46         7

但是,如果您是负责以这种形式获取数据的人,我建议您修复上游代码,从一开始就使用列表会更干净。

数据

Cluster_1_N1 <-read.table(text=
                            "ID   counts_N1
                          1       405
                          2         6
                          3       201
                          4        40",h=T,strin=F)

Cluster_1_N2 <-read.table(text=
                            "ID   counts_N2
                          1       657
                          2         9
                          3       250
                          4        77",h=T,strin=F)

Cluster_2_N1 <-read.table(text=
                            "ID   counts_N1
                          1         1
                          2         7
                          3        58
                          4        46",h=T,strin=F)

Cluster_2_N2 <-read.table(text=
                            "ID   counts_N2
                          1       652
                          2         3
                          3         2
                          4         7",h=T,strin=F)

【讨论】:

  • 非常感谢您的回答!不过还有一个小问题:由于我的数据帧的行数不同,我如何在您提出的代码中指定“all = True”合并参数?
  • 不客气,尝试将f= merge 替换为f = function(x,y) merge(x,y, all = TRUE)
  • 完美运行!谢谢!!
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 2018-10-28
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
相关资源
最近更新 更多