【问题标题】:create new columns within Data table dynamically from input vector从输入向量动态地在数据表中创建新列
【发布时间】:2019-03-15 00:28:44
【问题描述】:

所以我试图在现有 data.table 中动态创建新列,而不使用 eval(parse()) 选项。

data.table如下

library(data.table)
dt<-data.table(
  Jan01 = c(1:12), 
  Feb01 = c(100:111),
  Mar01 = c(25:36),
  Jan02 = c(5:10), 
  Feb02 = c(13:24),
  Mar02 = c(25:36),
  Jan03 = c(60:61), 
  Feb03 = c(70:71),
  Mar03 = c(40:51))

这将返回以下data.table

    Jan01 Feb01 Mar01 Jan02 Feb02 Mar02 Jan03 Feb03 Mar03
 1:     1   100    25     5    13    25    60    70    40
 2:     2   101    26     6    14    26    61    71    41
 3:     3   102    27     7    15    27    60    70    42
 4:     4   103    28     8    16    28    61    71    43
 5:     5   104    29     9    17    29    60    70    44
 6:     6   105    30    10    18    30    61    71    45
 7:     7   106    31     5    19    31    60    70    46
 8:     8   107    32     6    20    32    61    71    47
 9:     9   108    33     7    21    33    60    70    48
10:    10   109    34     8    22    34    61    71    49
11:    11   110    35     9    23    35    60    70    50
12:    12   111    36    10    24    36    61    71    51

我想做的是将所有 01 列汇总为一列,02 列等。下面的代码显示这是长格式

dt <- dt[, ':=' (
            All01 = (Jan01 + Feb01 + Mar01),
            All02 = (Jan02 + Feb02 + Mar02),
            All03 = (Jan03 + Feb03 + Mar03)
            )]

这将产生下表

    Jan01 Feb01 Mar01 Jan02 Feb02 Mar02 Jan03 Feb03 Mar03 All01 All02 All03
 1:     1   100    25     5    13    25    60    70    40   126    43   170
 2:     2   101    26     6    14    26    61    71    41   129    46   173
 3:     3   102    27     7    15    27    60    70    42   132    49   172
 4:     4   103    28     8    16    28    61    71    43   135    52   175
 5:     5   104    29     9    17    29    60    70    44   138    55   174
 6:     6   105    30    10    18    30    61    71    45   141    58   177
 7:     7   106    31     5    19    31    60    70    46   144    55   176
 8:     8   107    32     6    20    32    61    71    47   147    58   179
 9:     9   108    33     7    21    33    60    70    48   150    61   178
10:    10   109    34     8    22    34    61    71    49   153    64   181
11:    11   110    35     9    23    35    60    70    50   156    67   180
12:    12   111    36    10    24    36    61    71    51   159    70   183

我在制作函数前一年尝试使用以下方法对其进行测试,但它不起作用

x <- "01"

dt1<-dt[, ':=' (paste0("All",x) = (paste0("Jan",x) + paste0("Feb",x) + paste0("Mar", x)]

有错误

Error: unexpected '=' in "dt1<-dt[, ':=' (paste0("All",x) ="

最终目标是做这样的事情

myfunction<-function(Year){
  dt[, ':=' (paste0("All",Year) = (paste0("Jan",Year) + paste0("Feb",Year) + paste0("Mar", Year)]
}

obj <- lapply(c("01","02", "03"), Year)

【问题讨论】:

  • 最后一行,for (y in sprintf("%02d", 1:3)) myfunction(y) 比 lapply 更有意义,因为该函数对它的副作用有用,而不是它的返回值。

标签: r data.table


【解决方案1】:
myfunction <- function(Year) {
    dt[, paste0("All", Year) := rowSums(.SD), .SDcols = grep(paste0(Year, "$"), names(dt))]
}

【讨论】:

  • 非常感谢。我有一个跟进。如果我想按季度(例如 Jan-Mar、Apr-Jun 等)分组怎么办,我该如何编辑您必须仅聚合这些特定列的内容?
  • 你可以试试这样的:quarter_sum &lt;- function(quarter) {pat &lt;- paste0("(", paste0(month.abb[(3*(quarter-1)+1):(3*quarter)], collapse = "|"), ")"); cols &lt;- grep(pat, names(dt)); dt[, paste0("Quarter", quarter) := rowSums(.SD), .SDcols = cols] }。这使用了内置常量month.abb,检查它是否与您的月份名称匹配,否则创建一个类似的向量并在函数中替换它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 2017-11-16
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多