【问题标题】:Sum and replace columns with same name R for a data frame containing different classes对包含不同类的数据框求和并替换具有相同名称 R 的列
【发布时间】:2015-01-08 11:49:24
【问题描述】:

我有一个包含多个类的数据框,我想对那些具有相同名称且为数字的列求和,并将旧列替换为新的总和,有人知道这样做的方法吗?

即我有一个像这样的数据框:

col1 col2  col3 col3 
char factor int int

我想制作

col1  col2  col3 
char factor 2int

我以前用过:

data <- as.data.frame(do.call(cbind, by(t(data),INDICES=names(data),FUN=colSums)))

但是,这是在只有数字变量的数据帧上。

网上还有其他例子,但不满足条件:替换,保留框架的其余部分,以及在具有多个类的框架上

类似问题:how do I search for columns with same name, add the column values and replace these columns with same name by their sum? Using R

【问题讨论】:

  • 您是否有两个col2 col2 不属于同一类的情况?
  • @akrun 不是所有同名的列都是同一个类(数字)
  • 这不就是data$new_col &lt;- rowSums(data[sapply(data, is.integer)])然后删除这些列吗?
  • @DavidArenburg 它必须匹配重复的列名。

标签: r


【解决方案1】:

试试

dat1 <- dat #to keep a copy of the original dataset 
indx <- sapply(dat, is.numeric)#check which columns are numeric
nm1 <- which(indx)#get the numeric index of the column
indx2 <- duplicated(names(nm1))#check which among the
# integer columns are duplicated
#use `Map` after splitting the "nm1" with its "names", do the `rowSums`
dat[ nm1[!indx2]] <- Map(function(x,y) rowSums(x[y]), list(dat),
                                       split(nm1, names(nm1)))

 dat[ -nm1[indx2]]

更新

或者为了提高效率,只取“重复”和“数字”列,而其他列保持不变。创建重复列的“索引”(indx2)。基于“indx2”对“nm1”进行子集化,然后如上所述执行rowSums。最后,使用“indx3”删除不需要的列(重复的列)

 indx2 <- duplicated(names(nm1))|duplicated(names(nm1),fromLast=TRUE)
 nm2 <- nm1[indx2]
 indx3 <- duplicated(names(nm2))
 dat[nm2[!indx3]] <- Map(function(x,y) rowSums(x[y]), 
                list(dat),split(nm2, names(nm2)))
 datN <- dat[ -nm2[indx3]]
 datN
 #    col1 col2 col3 col4 col5
 #1    16   23    2   10   10
 #2    10   18   12    8   18
 #3    21   23   15    6   10
 #4    14   37    3    5   15
 #5    29   39    5    1   11
 #6    26   31   14    2   20
 #7    25   31    2    8   10
 #8    36   31   12    8    6
 #9    32   26   13    6    4
 #10   16   38    1    7    3

检查结果

 rowSums(dat1[names(dat1) %in% 'col1'])
 #[1] 16 10 21 14 29 26 25 36 32 16
 rowSums(dat1[names(dat1) %in% 'col2'])
 #[1] 23 18 23 37 39 31 31 31 26 38

数据

dat <- structure(list(col1 = c(6L, 5L, 15L, 11L, 14L, 19L, 6L, 16L, 
17L, 6L), col2 = c(13L, 8L, 14L, 14L, 7L, 19L, 4L, 1L, 11L, 3L
), col3 = structure(c(2L, 5L, 8L, 3L, 4L, 7L, 2L, 5L, 6L, 1L), .Label = c("1", 
"2", "3", "5", "12", "13", "14", "15"), class = "factor"), col2 = c(7L, 
5L, 8L, 3L, 19L, 5L, 15L, 13L, 14L, 20L), col4 = structure(c(7L, 
6L, 4L, 3L, 1L, 2L, 6L, 6L, 4L, 5L), .Label = c("1", "2", "5", 
"6", "7", "8", "10"), class = "factor"), col5 = c(10L, 18L, 10L, 
15L, 11L, 20L, 10L, 6L, 4L, 3L), col1 = c(10L, 5L, 6L, 3L, 15L, 
7L, 19L, 20L, 15L, 10L), col2 = c(3L, 5L, 1L, 20L, 13L, 7L, 12L, 
17L, 1L, 15L)), .Names = c("col1", "col2", "col3", "col2", "col4", 
"col5", "col1", "col2"), row.names = c(NA, -10L), class = "data.frame")

【讨论】:

  • 感谢解决方案非常好的代码!您知道是否可以按照您编写的方式将 reorder 函数传递给 rowSums?
  • 是否可以修改您的答案以保留行顺序?我犯了一个错误,我的意思是把 'reorder' 参数传递给 'rowSums' 函数。
  • @user1987097 在我创建的示例中,保留了行顺序。不知道为什么不保存
  • @user1987097 如果你看代码,我没有做任何改变行顺序的事情。
  • rowsums 函数的 reorder 参数默认为 TRUE,如果你不提供 reorder = FALSE 它会自动执行。这对于排序很重要的数据集来说是有问题的。
猜你喜欢
  • 2021-05-15
  • 2019-07-06
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-28
  • 2014-08-25
  • 2017-09-30
相关资源
最近更新 更多