【问题标题】:R - Sum Columns with specific prefixesR - 总和具有特定前缀的列
【发布时间】:2016-06-06 09:44:13
【问题描述】:

我在内存中有一个 data.table 表。它由具有这些列的许多行组成

key, c1.min, c2.min, c3.min, c1.max, c2.max, c3.max, c1.sd, c2.sd, c3.sd

我想返回一个新表

key, c1, c2, c3

在哪里

c1 = c1.min + c1.max + c1.sd
c2 = c2.min + c2.max + c2.sd
c3 = c3.min + c3.max + c3.sd

【问题讨论】:

  • 没关系,但问题出在哪里?
  • 另外,c1 不应该是...+c1.max+... 吗?
  • Sotos,是的,已修复。 @docendodiscimus,我将不胜感激语法方面的帮助
  • 您被否决的原因可能是您没有提供可重现的示例(请参阅minimal reproducible examplehere)并且您没有展示您所做的任何努力。你应该可以做类似dt[, list(c1 = c1.min + c1.max + c1.sd, c2 = c2.min + c2.max + c2.sd, c3 = c3.min + c3.max + c3.sd), by = key] 或类似的事情
  • 好的——够公平的,虽然这是我试图解决的一个更大问题的一部分。我的问题是属性是动态的,具体取决于环境,因此努力寻找适用于 c1、c2、...、cn 的解决方案。看起来我需要一些 lambda 函数。当我有解决方案时,我会发布解决方案,你可以给我 2 分...

标签: r data.table


【解决方案1】:

试试这个例子:

library(data.table)

#dummy data
myData <- 
  data.table(
    data.frame(
      key = 1:10,
      c1.min = 1:10,
      c2.min = 10:19,
      c3.min = 100:109,
      c1.max = 1:10,
      c2.max = 1:10,
      c3.max = 1:10,
      c1.sd = 1:10,
      c2.sd = 1:10,
      c3.sd = 1:10))

# using basic regex match
cbind(key = myData$key,
      sapply(c("c1", "c2", "c3"),function(i){
        myColnames <- colnames(myData)
        rowSums(myData[, grepl(i, myColnames), with = FALSE])
      }))

# using manual sum
myData[ , list(key,
               c1 = c1.min + c1.max + c1.sd,
               c2 = c2.min + c2.max + c2.sd,
               c3 = c3.min + c3.max + c3.sd) ]

【讨论】:

    【解决方案2】:

    这里有一个与melt 略有不同的选项。我们在measure参数中指定patterns,转换为'long'格式,然后按'key'分组并指定.SDcols,得到这些列的sum

    melt(myData, measure = patterns("^c1", "^c2", "^c3"),
      value.name = c('c1', 'c2', 'c3'))[, lapply(.SD, sum) , key, .SDcols = c1:c3]
    #    key c1 c2  c3
    # 1:   1  3 12 102
    # 2:   2  6 15 105
    # 3:   3  9 18 108
    # 4:   4 12 21 111
    # 5:   5 15 24 114
    # 6:   6 18 27 117
    # 7:   7 21 30 120
    # 8:   8 24 33 123
    # 9:   9 27 36 126
    #10:  10 30 39 129
    

    【讨论】:

      【解决方案3】:

      另一种选择:

      library(dplyr)
      library(tidyr)
      
      myData %>%
        gather(k, v, -key) %>%
        separate(k, into = c("l", "s")) %>%
        group_by(key, l) %>% 
        summarise(value = sum(v)) %>%
        spread(l, value)
      

      这给出了:

      #Source: local data frame [10 x 4]
      #Groups: key [10]
      #
      #     key    c1    c2    c3
      #*  <int> <int> <int> <int>
      #1      1     3    12   102
      #2      2     6    15   105
      #3      3     9    18   108
      #4      4    12    21   111
      #5      5    15    24   114
      #6      6    18    27   117
      #7      7    21    30   120
      #8      8    24    33   123
      #9      9    27    36   126
      #10    10    30    39   129
      

      【讨论】:

      • 也给你加一个。
      【解决方案4】:

      你可以使用基础包

      myData$c1 <- apply(myData[ ,c("c1.min","c1.max","c1.sd")] , 1 , sum)
      
      myData$c2 <- apply(myData[ ,c("c2.min","c2.max","c2.sd")] , 1 , sum)
      
      myData$c3 <- apply(myData[ ,c("c3.min","c3.max","c3.sd")] , 1 , sum)
      
      myData <- myData[,c("key","c1","c2","c3")]
      
      print(myData)
         key c1 c2  c3
      1    1  3 12 102
      2    2  6 15 105
      3    3  9 18 108
      4    4 12 21 111
      5    5 15 24 114
      6    6 18 27 117
      7    7 21 30 120
      8    8 24 33 123
      9    9 27 36 126
      10  10 30 39 129
      

      或者您可以为求和列定义一个函数

      abc <- function(x)apply(x,1,sum)
      
      c1 <- abc(myData[ ,c("c1.min","c1.max","c1.sd")])
      c2 <- abc(myData[ ,c("c2.min","c2.max","c2.sd")])
      c3 <- abc(myData[ ,c("c3.min","c3.max","c3.sd")])
      
      mydata1 <- as.data.frame(cbind(Key=myData$key,c1,c2,c3)) 
      
      > mydata1
         Key c1 c2  c3
      1    1  3 12 102
      2    2  6 15 105
      3    3  9 18 108
      4    4 12 21 111
      5    5 15 24 114
      6    6 18 27 117
      7    7 21 30 120
      8    8 24 33 123
      9    9 27 36 126
      10  10 30 39 129
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 2018-12-13
        • 2020-06-10
        相关资源
        最近更新 更多