【问题标题】:Merge duplicate columns and summing values in R合并R中的重复列和求和值
【发布时间】:2019-09-03 02:51:34
【问题描述】:

我有一个大矩阵,其中物种作为列,站点作为行。它是一个存在/不存在矩阵(即每个物种可以存在 = 1 或不存在 = 0)。

有些物种是重复的,但它们的值不一样(即同一物种可以出现在一个记录中,而在另一个记录中不存在)。

我需要合并列,即当一个物种被复制时,我只想保留一个记录并对所有值求和。

例如,给定这个矩阵:

A = matrix(c(1,0,1,1,1,1,0,0,1,1), nrow=2, ncol=5)
colnames(A)<-c("A","B","A","A","B")

   A B A A B
   1 1 1 0 1
   0 1 1 0 1

我想要的结果矩阵应该是:

   A B
   2 2
   1 2

但我的原始数据框中有 948 列和 454 行,这只是一个简单的示例。

我尝试转置然后聚合,但它不起作用。

【问题讨论】:

标签: r merge


【解决方案1】:

它基本上是一个循环,我们遍历每个唯一名称,然后使用 grepl 我们提取具有这些名称的列并执行行和

sapply(unique(colnames(A)), function(x) rowSums(A[,grepl(x, colnames(A))]))
#      A B
# [1,] 2 2
# [2,] 1 2

现在来解决您面临的问题:以下面的示例为例:

A = data.frame(c("JOEL", "WILSON"),c(1,0),c(1,1),c(1,1),c(0,0),c(1,1))
colnames(A)<-c("id","A","B","A","A","B")
#       id A B A A B
# 1   JOEL 1 1 1 0 1
# 2 WILSON 0 1 1 0 1

# assuming you have first column as factor(id) 
col <- unique(colnames(A))[-1]  # -1 means remove the first unique column name which in this case is "id" a factor column

cbind(A[1], sapply(col, function(x) rowSums(A[,grepl(x, colnames(A))])))
#      id A B
#1   JOEL 2 2
#2 WILSON 1 2

注意:我没有在这里对原始数据进行子集化,因为当我们这样做时,重复的列名现在附加了一个后缀:例如:-

A1 <- A[-1]
#A1
#  A B A.1 A.2 B.1
#1 1 1   1   0   1
#2 0 1   1   0   1

因此,您遇到了问题。希望对你有帮助!

让我们进入调试模式,因为您仍然遇到错误:

func <- function(x){
  w <- grepl(x, colnames(A))
  h <- A[, w]
  rowSums(h)
}  
debug(func)  
sapply(col, func)   # col is as above

现在逐步检查func..

【讨论】:

  • 嗨乔尔!谢谢你,它看起来很有希望,但我收到了这个错误:rowSums中的错误(Diatosdef [,grepl(x,colnames(Diatosdef))]):'x'必须是至少二维的数组调用自:rowSums (Diatosdef[, grepl(x, colnames(Diatosdef))]) 这里是调试: if (!is.array(x) || length(dn
  • @user2963185 你错过了, 里面的A[,...] 吗?这很重要
  • 嗨乔!我没有。我的数据名为“Diatosdef”。这是我使用的代码。我认为这正是您提供的那个: sapply(unique(colnames(Diatosdef)), function(x) rowSums(Diatosdef[,grepl(x, colnames(Diatosdef))]))
  • @user2963185 看起来很奇怪......请注意分享 class(Diatosdef)str(Diatosdef) 输出......x 只是名称,不需要是二维的......我不确定现在的原因......可能需要更多细节
  • 嗨乔尔!感谢您继续提供帮助!类为data.frame,结构:data.frame: 454 obs。 951 个变量。第一个变量 = 454 个水平的因子;其余变量 = num
【解决方案2】:

按照这篇文章中的说明,我通过转置矩阵然后对行求和找到了解决方案:Checking duplicates, sum them and delete one row after summing

【讨论】:

    【解决方案3】:

    Joel Wilson 的代码差不多就在那里,但关注的是唯一列而不是重复列。我在这里的回答是对 Joel 的代码稍作修改,改为专注于重复的列。

    # two functions
    df2 <- sapply(unique(colnames(df)[duplicated(colnames(df))]), function(x) rowSums(df[,grepl(paste(x, "$", sep=""), colnames(df))]))
    df2 <- cbind(df2, df[,!duplicated(colnames(df)) & !duplicated(colnames(df), fromLast = TRUE)])
    
    # one long function
    df2 <- cbind(sapply(unique(colnames(df)[duplicated(colnames(df))]), function(x) rowSums(df[,grepl(paste(x, "$", sep=""), colnames(df))])), df[,!duplicated(colnames(df)) & !duplicated(colnames(df), fromLast = TRUE)])
    

    说明

    建立答案,首先查看列名:

    colnames(df)

    创建指示重复列的逻辑向量:

    duplicated(colnames(df))

    返回重复列名的列名(听起来很迂回,但逻辑向量正在选择重复列,然后colnames 返回名称):

    colnames(df)[duplicated(colnames(df))]

    unique 函数包装它以返回每个重复列的单个副本:

    unique(colnames(df)[duplicated(colnames(df))])

    使用此代码代替 Joel Wilson 的列名代码 unique(colnames(A))

    sapply(unique(colnames(df)[duplicated(colnames(df))]), function(x) rowSums(df[,grepl(x, colnames(df))]))

    我们在这里所做的是使用重复列的名称创建一个向量,然后在这些名称上迭代地应用一个函数。对于每个列名,R 搜索数据框并选择具有该名称的列并对它们的行求和。

    最后,将此函数分配给一个新的数据框,并将未求和的列(没有重复名称的列)加回。

    df2 <- sapply(unique(colnames(df)[duplicated(colnames(df))]), function(x) rowSums(df[,grepl(paste(x, "$", sep=""), colnames(df))]))
    df2 <- cbind(df2, df[,!duplicated(colnames(df)) & !duplicated(colnames(df), fromLast = TRUE)])
    

    编辑

    我不知道duplicate 函数将第一次出现的重复名称标记为FALSE。我发现这个post 有助于调试我的答案,这样第一次出现的重复列就不会包含在最终数据集中。

    编辑 2

    在实践中使用此代码,我发现正则表达式搜索对作为彼此子集的列求和。例如,如果有名为 OTU_3、OTU_35 和 OTU_301 的列,则所有名为 OTU_35 的列将被折叠和求和,所有名为 OTU_301 的列将被折叠和求和,但 OTU_3 将是名为 OTU_3、OTU_35 和OTU_301。将正则表达式从 x 更改为 paste(x, "$", sep="") 可解决此问题。美元符号表示 x 之后不应该有任何其他字符才能成功匹配。

    【讨论】:

      猜你喜欢
      • 2021-10-19
      • 1970-01-01
      • 2020-02-03
      • 2016-08-16
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 2016-08-17
      相关资源
      最近更新 更多