【问题标题】:Subset by column criteria AND randomly sample rows of a data.table按列标准和随机抽样 data.table 的行
【发布时间】:2019-07-04 17:54:34
【问题描述】:

@gented 的回答 here 演示了如何从 data.table 中随机选择行的子集。

如果我想选择 data.table 中某一列中的值满足特定条件的所有行,并另外从 data.table 中选择同一列中的值的随机行子集,该怎么办?满足不同的条件?

假设,例如,我想要从mtcars data.table 中随机抽取 5 行样本,其中 cyl == 6 cyl == 8 的所有行。

这是否比以下方式更好:

rbind(
    mtcars[ cyl == 8 ],
    mtcars[ cyl == 6 ][ sample(.N, 5) ]
)

也就是说,我是否可以将data.table 子集到一组[] 中,以便例如在该调用中应用一个函数(以lapply(.SD, function) 格式)?

这显然没有达到预期的结果,但与我正在寻找的语法相似:

mtcars[ 
    cyl == 8 | ( cyl == 6 & sample( .N, 5 ) ), 
    lapply(.SD, generic_funciton), 
    .SDcols = (specific_cols) 
]

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    为此,我将使用.I 特殊符号,如下所示:

    DT <- as.data.table(mtcars)
    
    DT[c(DT[, .I[cyl == 8]], sample(DT[, .I[cyl == 6]], 5))]
    

    现在你可以做一些计算了:

    set.seed(2019)
    DT[c(DT[, .I[cyl == 8]], sample(DT[, .I[cyl == 6]], 5))
       , lapply(.SD, mean)
       , by = am
       , .SDcols = 3:5]
    

    给出:

       am   disp       hp     drat
    1:  0 325.64 179.0667 3.224667
    2:  1 243.00 204.7500 3.890000
    

    如果你想在以后重用那个索引向量,你可以预先存储它:

    idx <- c(DT[, .I[cyl == 8]], sample(DT[, .I[cyl == 6]], 5))
    
    DT[idx, lapply(.SD, mean), .SDcols = 3:5]
    

    【讨论】:

      【解决方案2】:

      只要i 最终得到可用于选择行的东西, 你可以在那里放任何有效的表达, 这在技术上意味着你可以写:

      DT[c(sample(which(cyl == 6), 5L), which(cyl == 8))]
      

      但这可能不会从optimizations 中受益。

      基于this answer (和secondary indices), 我认为这样的事情会更快:

      sample_if <- function(condition, values, n) {
        if (condition)
          sample(values, n)
        else
          values
      }
      
      some_fun <- function(.SD) {
        .SD
      }
      
      DT[DT[.(c(6, 8)), sample_if(.BY$cyl == 6, .I, 5L), by = "cyl", on = "cyl"]$V1,
         some_fun(.SD),
         .SDcols = c("cyl", "mpg")]
          cyl  mpg
       1:   6 19.7
       2:   6 19.2
       3:   6 21.4
       4:   6 21.0
       5:   6 18.1
       6:   8 18.7
       7:   8 14.3
       8:   8 16.4
       9:   8 17.3
      10:   8 15.2
      11:   8 10.4
      12:   8 10.4
      13:   8 14.7
      14:   8 15.5
      15:   8 15.2
      16:   8 13.3
      17:   8 19.2
      18:   8 15.8
      19:   8 15.0
      

      【讨论】:

        猜你喜欢
        • 2019-12-28
        • 2013-08-17
        • 1970-01-01
        • 2018-08-07
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 1970-01-01
        • 2016-11-19
        相关资源
        最近更新 更多