【问题标题】:R Summary based on column name lengthR基于列名长度的摘要
【发布时间】:2013-07-08 14:26:48
【问题描述】:

我有以下问题: 我有一个包含 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() 执行操作。但是,我无法将其转换回我真正需要作为最终输出的矩阵。列没有按顺序排列,排序对我没有多大帮助,因为列数取决于先前计算的结果,并且每次再次定义数据框范围都太乏味了。 希望你能帮忙。

【问题讨论】:

    标签: r dataframe summary


    【解决方案1】:

    你想要这个:

    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
    

    【讨论】:

    • 感谢 Thomas 完成了这项工作。如果我想单独获得每一行的值,甚至附加到数据框 g,我需要更改什么?
    • 看看rowSums 而不是sum。这将返回每个列分组的行和向量,然后您可以轻松地将其 cbind 到原始 df。
    • 适用于示例提供。如果我添加长度为 4 的另一列(例如“hhhh”),则会出现以下错误:“base::rowSums(x, na.rm = na.rm, dims = dims, ...) 中的错误:' x' 必须是至少二维的数组”如何解释这个问题?在手册中提供的帮助下,我无法做到这一点。命令中的“x”代表什么,它是在哪里生成的?抱歉,如果这些问题看起来很愚蠢,但我不完全理解您的代码为何有效。但是,对于我提供的示例,它确实如此。
    • @user2386786 查看编辑。 rowSums 不接受向量作为其输入,只接受一个 2+ 维数组,因此如果有多个列是组,则代码现在将为您提供行总和,如果只有一栏。
    【解决方案2】:

    另一种方法

    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 ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-18
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 2014-05-27
      • 2020-11-22
      • 1970-01-01
      相关资源
      最近更新 更多