【问题标题】:Data.table selecting columns by name, e.g. using greplData.table 按名称选择列,例如使用 grepl
【发布时间】:2016-08-05 15:18:28
【问题描述】:

假设我有以下data.table:

dt <- data.table("x1"=c(1:10), "x2"=c(1:10),"y1"=c(10:1),"y2"=c(10:1), desc = c("a","a","a","b","b","b","b","b","c","c"))

我想通过 desc 对以“x”开头的列求和,并对以“y”开头的列求和。目前我这样做是:

dt[,.(Sumx=sum(x1,x2), Sumy=sum(y1,y2)), by=desc]

这可行,但我想通过列名来引用所有带有“x”或“y”的列,例如使用 grepl()。

请您告诉我该怎么做?我想我需要使用 with=FALSE,但不能让它与 by=desc 结合使用?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    单线:

    melt(dt, id="desc", measure.vars=patterns("^x", "^y"), value.name=c("x","y"))[, 
      lapply(.SD, sum), by=desc, .SDcols=x:y]
    

    长版(@Frank):

    首先,您可能不想这样存储数据。而是……

    m = melt(dt, id="desc", measure.vars=patterns("^x", "^y"), value.name=c("x","y"))
    
        desc variable  x  y
     1:    a        1  1 10
     2:    a        1  2  9
     3:    a        1  3  8
     4:    b        1  4  7
     5:    b        1  5  6
     6:    b        1  6  5
     7:    b        1  7  4
     8:    b        1  8  3
     9:    c        1  9  2
    10:    c        1 10  1
    11:    a        2  1 10
    12:    a        2  2  9
    13:    a        2  3  8
    14:    b        2  4  7
    15:    b        2  5  6
    16:    b        2  6  5
    17:    b        2  7  4
    18:    b        2  8  3
    19:    c        2  9  2
    20:    c        2 10  1
    

    那你就可以了……

    setnames(m[, lapply(.SD, sum), by=desc, .SDcols=x:y], 2:3, paste0("Sum", c("x", "y")))[]
    #   desc Sumx Sumy
    #1:    a   12   54
    #2:    b   60   50
    #3:    c   38    6
    

    有关改进您正在使用的数据结构的更多信息,请阅读tidying data

    【讨论】:

    • @Frank 不,感谢您的编辑。我正在编辑。
    • @Frank 很好,你做了一些有价值的编辑。我想添加 setnames 以将其更改为 OP 的预期。
    • 是的,如何构建我的数据仍然是一个学习曲线!感谢您的建议。
    【解决方案2】:

    使用mgetgrep是一个选项,其中grep("^x", ...)返回以x开头的列名并使用mget获取列数据,unlist结果然后你可以计算sum

    dt[,.(Sumx=sum(unlist(mget(grep("^x", names(dt), value = T)))), 
          Sumy=sum(unlist(mget(grep("^y", names(dt), value = T))))), by=desc]
    
    #   desc Sumx Sumy
    #1:    a   12   54
    #2:    b   60   50
    #3:    c   38    6
    

    【讨论】:

      猜你喜欢
      • 2020-01-23
      • 2020-08-23
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 2023-01-31
      相关资源
      最近更新 更多