合并R中的重复列和求和值

时间:2017-02-07 19:49:38

标签: r merge

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

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

我需要合并列,即当物种重复时我想只保留一条记录并总结所有值。

例如,给定此矩阵:

   A B
   2 2
   1 2

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

public Hawk extends Animal

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

我试图进行转置,然后进行汇总,但它无效。

3 个答案:

答案 0 :(得分:0)

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

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

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

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 ..

答案 1 :(得分:0)

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

答案 2 :(得分:0)

乔尔·威尔逊(Joel Wilson)的代码就在那里,但专注于唯一列而不是重复列。我在这里的答案是对Joel的代码进行了一些修改,以使其专注于重复的列。

df2 <- sapply(unique(colnames(df)[duplicated(colnames(df))]), function(x) rowSums(df[,grepl(x, colnames(df))]))
df2 <- cbind(df2, 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(x, colnames(df))]))
df2 <- cbind(df2, df[,!duplicated(colnames(df)) & !duplicated(colnames(df), fromLast = TRUE)])

编辑

我不知道duplicate函数将第一次出现的重复名称标记为FALSE。我发现此post对调试我的答案很有帮助,因此第一次出现重复列的操作不会包含在最终数据集中。