我一直在尝试使用data.table。但是我并不总是完全了解语法。我在代码中找到了这一行,但无法弄清楚它的作用。有人可以向我解释吗?
df <- setDT(df)[, .SD[1], by = .(ID, year)]
尤其关注他在[1]
中SD[1]
。是否与将每个ID年的行设置为子行有关?
答案 0 :(得分:3)
.SD[1]
选择每个组的第一行。这里的组由by
指定,分别是ID
和year
。
我们可以使用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
因此,它在这里从cyl
和am
中选择第一行。
答案 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