R基于列名长度的摘要

时间:2013-07-08 14:26:48

标签: r dataframe summary

我有以下问题: 我有一个80列的矩阵,名称有10 / 11,21 / 22,31 / 32或42/43字符。名字完全不同,但长度总是适合四个组中的一个。现在我想添加四列,我得到对应于一个组的列的所有值的总和。这是我的意思的一个小例子

a<-rnorm(1:100)
b<-rnorm(1:100)
cc<-rnorm(1:100)
dd<-rnorm(1:100)
eee<-rnorm(1:100)
fff<-rnorm(1:100)
g<-data.frame(a,b,cc,dd,eee,fff)
g$group1<-"sum of all columns of with headers of length 1 (in this case a+b)"
g$group2<-"sum of all columns of with headers of length 2 (in this case cc+dd)"
g$group3<-"sum of all columns of with headers of length 3 (in this case eee+fff)"

我能够使用melt()将矩阵传输到数据帧,并使用stringr :: str_length()执行操作。但是,我无法将其转换回我真正需要作为最终输出的矩阵。列不是有序的,排序对我没有多大帮助,因为列的数量取决于先前计算的结果,并且每次再次定义数据帧范围将太繁琐。 希望你能帮忙。

2 个答案:

答案 0 :(得分:0)

你想要这个:

tmp <- nchar(names(g))
chargroups <- split(1:dim(g)[2], tmp)
# `chargroups` is a list of groups of columns with same number of letters in name
sapply(chargroups, function(x) {
    if(length(x)>1) # rowSums can only accept 2+-dimensional object
        rowSums(g[,x])
    else
        g[,x]
})
# `x` is, for each number of letters, a vector of column indices of `g`

关键部分是nchar将确定列名称的长度。其余的很简单。

编辑:在您的实际代码中,虽然您应该在定义tmp之后但在sapply语句之前执行类似以下的操作来处理名称长度范围:

tmp[tmp==10] <- 11
tmp[tmp==21] <- 22
tmp[tmp==31] <- 32
tmp[tmp==32] <- 43

答案 1 :(得分:0)

另一种方法

set.seed(123)
a <- rnorm(1:100)
b <- rnorm(1:100)
cc <- rnorm(1:100)
dd <- rnorm(1:100)
eee <- rnorm(1:100)
fff <- rnorm(1:100)
g <- data.frame(a,b,cc,dd,eee,fff)

for ( i in 1:3 )
    eval(parse(text = sprintf("g$group%s <- rowSums(g[nchar(names(g)) == %s])", i, i)))

## 'data.frame':    100 obs. of  9 variables:
##  $ a     : num  -0.5605 -0.2302 1.5587 0.0705 0.1293 ...
##  $ b     : num  -0.71 0.257 -0.247 -0.348 -0.952 ...
##  $ cc    : num  2.199 1.312 -0.265 0.543 -0.414 ...
##  $ dd    : num  -0.715 -0.753 -0.939 -1.053 -0.437 ...
##  $ eee   : num  -0.0736 -1.1687 -0.6347 -0.0288 0.6707 ...
##  $ fff   : num  -0.602 -0.994 1.027 0.751 -1.509 ...
##  $ group1: num  -1.2709 0.0267 1.312 -0.277 -0.8223 ...
##  $ group2: num  1.484 0.56 -1.204 -0.509 -0.851 ...
##  $ group3: num  -0.675 -2.162 0.392 0.722 -0.838 ...