【问题标题】:Divide data.table rows by overall mean将 data.table 行除以总体平均值
【发布时间】:2015-10-28 17:11:37
【问题描述】:

考虑以下

mtcars.dt <- data.table(mtcars)
DT1 = mtcars.dt[, lapply(.SD, mean), by=cyl]
DT2 = mtcars.dt[, lapply(.SD, mean)]

现在,我们有以下值:

> DT1
   cyl      mpg     disp        hp     drat       wt     qsec        vs        am     gear     carb
1:   6 19.74286 183.3143 122.28571 3.585714 3.117143 17.97714 0.5714286 0.4285714 3.857143 3.428571
2:   4 26.66364 105.1364  82.63636 4.070909 2.285727 19.13727 0.9090909 0.7272727 4.090909 1.545455
3:   8 15.10000 353.1000 209.21429 3.229286 3.999214 16.77214 0.0000000 0.1428571 3.285714 3.500000

> DT2
        mpg    cyl     disp       hp     drat      wt     qsec     vs      am   gear   carb
1: 20.09062 6.1875 230.7219 146.6875 3.596563 3.21725 17.84875 0.4375 0.40625 3.6875 2.8125

现在,我想将 DT1 中每一行的 mpg、disp、... 归一化为整个原始表的平均值(在 DT2 中可用)。

我该怎么做?这里的正确成语是什么?

编辑:这是所需的输出,抱歉我之前没有更清楚。

    cyl      mpg      disp        hp      drat        wt      qsec       vs        am      gear      carb
1:    6 0.9826900 0.7945249 0.8336478 0.9969837 0.9688843 1.0071934 1.306122 1.0549451 1.0460048 1.2190476
2:    4 1.3271681 0.4556844 0.5633497 1.1318889 0.7104599 1.0721912 2.077922 1.7902098 1.1093991 0.5494949
3:    8 0.7515943 1.5304141 1.4262584 0.8978812 1.2430536 0.9396817 0.000000 0.3516484 0.8910412 1.2444444

【问题讨论】:

  • 试试DT1[, -1, with = FALSE]/unlist(DT2[, -2, with = FALSE])[col(DT1)]
  • @DavidArenburg 谢谢,但我如何取回结果中的 cyl 列?
  • 你能显示你想要的输出吗?不是很清楚
  • @DavidArenburg 抱歉,刚刚添加。
  • 你可以做cbind(DT1[, .(cyl)], DT1[, -1, with = FALSE]/unlist(DT2[, -2, with = FALSE])[col(DT1)]),但我觉得这不是很data.tableish。让我一秒钟制作更好的东西

标签: r data.table


【解决方案1】:

这是一个可能的更多data.tableish 解决方案,它使用高效的set 函数(我在 CRAN btw-v 1.9.6 上使用最新的data.table 版本)

创建DT1

library(data.table) # V 1.9.6+
mtcars.dt <- data.table(mtcars)
DT1 <- mtcars.dt[, lapply(.SD, mean), by = cyl]

现在创建DT2,同时通过在.SDcols 参数中取反来避免cyl

DT2 <- unlist(mtcars.dt[, lapply(.SD, mean), .SDcols = -"cyl"])

现在循环遍历DT1 中的第二列,然后更新DT1 就地,同时除以DT2 中的元素

for (j in 2L:length(DT1)) set(DT1, j = j, value = DT1[[j]]/DT2[j - 1L])
DT1
#    cyl       mpg      disp        hp      drat        wt      qsec       vs        am      gear      carb
# 1:   6 0.9826900 0.7945249 0.8336478 0.9969837 0.9688843 1.0071934 1.306122 1.0549451 1.0460048 1.2190476
# 2:   4 1.3271681 0.4556844 0.5633497 1.1318889 0.7104599 1.0721912 2.077922 1.7902098 1.1093991 0.5494949
# 3:   8 0.7515943 1.5304141 1.4262584 0.8978812 1.2430536 0.9396817 0.000000 0.3516484 0.8910412 1.2444444

【讨论】:

    【解决方案2】:
    mapply('/',subset(DT1, select=-cyl), subset(DT2, select=-cyl))
    

    但这只是数据帧

    【讨论】:

      【解决方案3】:

      每行标准化然后通过 cyl 聚合可以解决您的问题吗?

      像这样: mtcars.dt

      # normalise by cyl
      sdcol <- names(mtcars.dt)[names(mtcars.dt) != "cyl"]
      res <- mtcars.dt[, lapply(.SD, function(x) x / mean(x)), .SDcols = sdcol]
      res[, cyl := mtcars.dt[, cyl]]
      
      # aggregate
      res2 <- res[, lapply(.SD, mean), by = cyl]
      

      或短版:

      mtcars.dt[, lapply(.SD, function(x) x / mean(x)), .SDcols = sdcol][, cyl := mtcars.dt[, cyl]][, lapply(.SD, mean), by = cyl]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-26
        • 2015-05-01
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 2017-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多