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 之后不应该有任何其他字符才能成功匹配。