在data.table语法上遇到麻烦

时间:2019-08-02 07:55:14

标签: r syntax data.table

我一直在尝试使用data.table。但是我并不总是完全了解语法。我在代码中找到了这一行,但无法弄清楚它的作用。有人可以向我解释吗?

df <- setDT(df)[, .SD[1], by = .(ID, year)]

尤其关注他在[1]SD[1]。是否与将每个ID年的行设置为子行有关?

2 个答案:

答案 0 :(得分:3)

.SD[1]选择每个组的第一行。这里的组由by指定,分别是IDyear

我们可以使用mtcars数据集为例

df <- mtcars
setDT(df)[,.SD[1L], by = .(cyl, am)]

#   cyl am  mpg  disp  hp drat    wt  qsec vs gear carb
#1:   6  1 21.0 160.0 110 3.90 2.620 16.46  0    4    4
#2:   4  1 22.8 108.0  93 3.85 2.320 18.61  1    4    1
#3:   6  0 21.4 258.0 110 3.08 3.215 19.44  1    3    1
#4:   8  0 18.7 360.0 175 3.15 3.440 17.02  0    3    2
#5:   4  0 24.4 146.7  62 3.69 3.190 20.00  1    4    2
#6:   8  1 15.8 351.0 264 4.22 3.170 14.50  0    5    4

因此,它在这里从cylam中选择第一行。

答案 1 :(得分:2)

我们可以使用.I来提高效率

library(data.table)
df <- copy(mtcars)
setDT(df)[df[, .I[1L], by = .(cyl, am)]$V1]
#.    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#2: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#3: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#4: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#5: 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#6: 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4

基准

set.seed(24)
dt <- data.table(grp = rep(1:1e6, each = 20), 
    as.data.frame(matrix(rnorm( 20000000 * 20), ncol = 20)))

system.time({

    dt[,.SD[1L], by = .(grp)]
    })
#   user  system elapsed 
#  2.018   0.309   0.532 
    system.time({

       dt[dt[, .I[1L], by = .(grp)]$V1]

    })
#   user  system elapsed 
# 1.218   0.327   0.273