【问题标题】:Product of list of columns in R data.tableR data.table 中列列表的乘积
【发布时间】:2020-10-14 13:04:08
【问题描述】:

我有一个 R data.table 的大量列名(变量)列表,我想创建一个包含这些列的乘积的列。

例子:

col_names <- c("season_1","season_2","season_3")
DT_example <- data.table(id=1:4,
                 season_1=c(1,1,0,0),
                 season_2=c(0,1,1,1),
                 season_3=c(1,0,1,0),
                 product=1)

数据表:

   id season_1 season_2 season_3 product
1:  1        1        0        1       1
2:  2        1        1        1       1
3:  3        0        1        1       1
4:  4        0        1        0       1

我的解决方案是使用“for”循环,但效率不高:

for(inc in col_names){
  nm1 <- as.symbol(inc)
  DT_example[,product:= product * eval(nm1)]
}

结果:

   id season_1 season_2 season_3 product
1:  1        1        0        1       0
2:  2        1        1        0       0
3:  3        1        1        1       1
4:  4        0        1        0       0

有没有更快的方法使用 data.table 原生语法来做到这一点?

【问题讨论】:

  • DT_example[, product := Reduce("*", .SD), .SDcols = col_names]
  • 显示的示例数据和重现它的代码不匹配。

标签: r data.table


【解决方案1】:

这里有四个选项。第一个是迄今为止最有效的,但假设我们只处理零和一。

DT_example[, product := do.call(pmin, .SD), .SDcols = patterns("season")]

DT_example[, product := Reduce(`*`, .SD), .SDcols = patterns("season")]

DT_example[, product := apply(.SD, 1, prod), .SDcols = patterns("season")]

DT_example[, product := melt(.SD, id.vars = "id")[, prod(value), by = id]$V1]

# > DT_example
#    id season_1 season_2 season_3 product
# 1:  1        1        0        1       0
# 2:  2        1        1        1       1
# 3:  3        0        1        1       0
# 4:  4        0        1        0       0

数据:

DT_example <- data.table(
  id=1:4,
  season_1=c(1,1,0,0),
  season_2=c(0,1,1,1),
  season_3=c(1,1,1,0),
  product=1
)

【讨论】:

    【解决方案2】:

    我认为您可以使用“应用”和“产品”功能:

    DT_example$product = apply(DT_example[,2:4], 1, prod)
    

    这是将“prod”函数(将 ir 接收的每个元素相乘)应用于“DT_example[,2:4 ]"。

    【讨论】:

      【解决方案3】:

      选择.SDcols中的列后,我们可以使用prod按行序列分组。使用prod,还有na.rm 选项,可以根据需要删除NA 元素。

      DT_example[,  Product := prod(.SD, na.rm = TRUE), by = 1:nrow(DT_example),
           .SDcols = patterns("season")]
      

      -输出

      DT_example
      #   id season_1 season_2 season_3 product Product
      #1:  1        1        0        1       1       0
      #2:  2        1        1        1       1       1
      #3:  3        0        1        1       1       0
      #4:  4        0        1        0       1       0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多