如何搜索具有相同名称的列,添加列值并使用相同的名称替换这些列的总和?使用R.

时间:2011-05-09 14:43:40

标签: r

我有一个数据框,其中一些连续的列具有相同的名称。我需要搜索这些,为每行添加它们的值,删除一列并用它们的总和替换另一列。 之前不知道哪些模式是重复的,可能需要将一个列名与下面的名称进行比较,以确定是否匹配。

有人可以帮忙吗?

提前致谢。

4 个答案:

答案 0 :(得分:7)

> dfrm <- data.frame(a = 1:10, b= 1:10, cc= 1:10, dd=1:10, ee=1:10)
> names(dfrm) <- c("a", "a", "b", "b", "b")
> sapply(unique(names(dfrm)[duplicated(names(dfrm))]), 
      function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]) )
       a  b
 [1,]  2  3
 [2,]  4  6
 [3,]  6  9
 [4,]  8 12
 [5,] 10 15
 [6,] 12 18
 [7,] 14 21
 [8,] 16 24
 [9,] 18 27
[10,] 20 30

编辑2:使用rowSums允许将第一个sapply参数简化为unique(names(dfrm)),代价是需要记住在“[”中包含drop = FALSE:

sapply(unique(names(dfrm)), 
       function(x) rowSums( dfrm[ , grep(x, names(dfrm)), drop=FALSE]) )

处理NA的问题:

sapply(unique(names(dfrm)), 
      function(x) apply(dfrm[grep(x, names(dfrm))], 1, 
              function(y) if ( all(is.na(y)) ) {NA} else { sum(y, na.rm=TRUE) }
       )               )

(编辑注释:通过在名称(。)[。]构造周围添加唯一性来解决Tommy反例。 错误的代码是:

sapply(names(dfrm)[unique(duplicated(names(dfrm)))], 
     function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]) )

答案 1 :(得分:4)

这是我的一个班轮

# transpose data frame, sum by group = rowname, transpose back.
t(rowsum(t(dfrm), group = rownames(t(dfrm))))

答案 2 :(得分:2)

一些示例数据。

dfr <- data.frame(
  foo = rnorm(20),
  bar = 1:20,
  bar = runif(20),
  check.names = FALSE
)

方法:循环唯一的列名称;如果只有一个名称,那么用该nme选择所有列将返回一个向量,但如果有重复,它也将是一个数据帧。使用rowSums对行进行求和。 ( Duh。编辑:不像以前想的那样'duh'!) lapply返回一个列表,我们需要将其改造成数据框,最后我们修复了名称。编辑:sapply避免了最后一步的需要。

unique_col_names <- unique(colnames(dfr))
new_dfr <- sapply(unique_col_names, function(name)
{
  subs <- dfr[, colnames(dfr) == name]
  if(is.data.frame(subs))
    rowSums(subs)
  else
    subs
})

答案 3 :(得分:1)

一种方法是使用(惊讶)duplicated函数识别重复项,然后循环遍历它们以计算总和。这是一个例子:

dat.dup <- data.frame(x=1:10, x=1:10, x=1:10, y=1:10, y=1:10, z=1:10, check.names=FALSE)
dups <- unique(names(dat.dup)[duplicated(names(dat.dup))])
for (i in dups) {
dat.dup[[i]] <- rowSums(dat.dup[names(dat.dup) == i])
}
dat <- dat.dup[!duplicated(names(dat.dup))]