我有一个大型矩阵,其中物种为列,站点为行。它是存在/不存在矩阵(即每个物种可以存在= 1或不存在= 0)。
有些物种是重复的,但它们的值不一样(即同一物种可以存在于一个记录中而在另一个记录中不存在)。
我需要合并列,即当物种重复时我想只保留一条记录并总结所有值。
例如,给定此矩阵:
A B
2 2
1 2
我想要的结果矩阵应该是:
public Hawk extends Animal
但我的原始数据框中有948列和454行,这只是一个简单的例子。
我试图进行转置,然后进行汇总,但它无效。
答案 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对调试我的答案很有帮助,因此第一次出现重复列的操作不会包含在最终数据集中。