@gented的答案here演示了如何从data.table
中随机选择行的子集。
如果我想选择data.table
中某个列中的值满足特定条件的所有行,并且另外从data.table
中选择一个行的随机子集作为值,该怎么办?在同一列中满足不同条件?
举例来说,我想从mtcars
data.table
中随机抽取5行样本,其中cyl == 6
,和的所有行均{ {1}}。
这是比以下方法更好的实现吗?
cyl == 8
也就是说,我可以将rbind(
mtcars[ cyl == 8 ],
mtcars[ cyl == 6 ][ sample(.N, 5) ]
)
包含在一组data.table
中吗?例如,我还可以在该调用中应用一个函数(在[]
中格式)?
这显然不能达到预期的结果,但是与我正在寻找的语法类似:
lapply(.SD, function)
答案 0 :(得分:1)
只要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
答案 1 :(得分: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]