另一种解决方案
dt[, .(dt[, 1], Freq = Prop * 1000)]
gender Freq
1: Male 490
2: Female 510
所有答案中给出的选项的一些基准
请注意,我增加了相当多的样本数据,但我也只是好奇其他数据集的方法之间的差异。
这里的转换非常慢,不推荐使用,其他方法非常相似,.SD 和 .SDcols 的功能是最快的,尽管在这种情况下,保留所有行并且不使用第一个引用更新任何内容方法几乎不会慢。
set.seed(42)
dt <- data.table(
gender = rep(LETTERS[1:25], 40000),
Prop = runif(n = 1000000))
library(rbenchmark)
benchmark(
"dt[, .(dt[, 1], Freq = Prop * 1000)]" = {
dt[, .(dt[, 1], Freq = Prop * 1000)]
},
"dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = 1]" = {
dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = 1]
},
"dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = -\"Prop\"]" = {
dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = -"Prop"]
},
"dt[, transform(.SD, Freq = Prop * 1000, Prop = NULL)]" = {
dt[, transform(.SD, Freq = Prop * 1000, Prop = NULL)]
},
"transform(dt, Freq = Prop * 1000, Prop = NULL)" = {
transform(dt, Freq = Prop * 1000, Prop = NULL)
},
replications = 1000,
columns = c("test", "replications", "elapsed", "relative")
)
# test replications elapsed relative
# 1 dt[, .(dt[, 1], Freq = Prop * 1000)] 1000 18.66 1.112
# 3 dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = -"Prop"] 1000 17.02 1.014
# 2 dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = 1] 1000 16.78 1.000
# 4 dt[, transform(.SD, Freq = Prop * 1000, Prop = NULL)] 1000 333.51 19.875
# 5 transform(dt, Freq = Prop * 1000, Prop = NULL) 1000 329.41 19.631
旁注
请记住,通过引用创建列的速度快了 5 倍
dt[, Freq := Prop * 1000] 和 OP 使用该表稍后重新使用的参数。我建议始终在速度加快时通过参考表格进行所有计算和准备工作。您始终可以从那里对输出进行子集化。
# test replications elapsed relative
# 1 dt[, .(dt[, 1], Freq = Prop * 1000)] 1000 16.25 5.783
# 2 dt[, c(.SD, .(Freq = Prop * 1000)), .SDcols = 1] 1000 13.33 4.744
# 3 t[, Freq := Prop * 1000] 1000 2.81 1.000