jon*_*nsh 3 r dataframe data.table
我有以下data.table内容R
dt <- data.table(gender = c("Male", "Female"), Prop = c(0.49, 0.51))
# gender Prop
# 1: Male 0.49
# 2: Female 0.51
Run Code Online (Sandbox Code Playgroud)
我想计算一Freq = Prop * 1000列,然后仅返回gender和Freq列。如何在一行代码中完成此操作,而无需显式引用该gender列且无需修改dt?
我能做到的最好的办法是:
onsdist$gender[, c(.SD, Freq = Prop * 1000)][, .SD, .SDcols = - "Prop"]
# gender Freq1 Freq2
# 1: Male 490 490
# 2: Female 510 510
Run Code Online (Sandbox Code Playgroud)
但我最终得到了重复的Freq列。
(我不想引用的原因gender是因为它跨data.tables改变了。我不想修改的原因dt是因为以后需要重新使用原始版本)。
1)使用 Prop = NULL 的变换
dt[, transform(.SD, Freq = Prop * 1000, Prop = NULL)]
## gender Freq
## 1: Male 490
## 2: Female 510
Run Code Online (Sandbox Code Playgroud)
2)或这种变体
transform(dt, Freq = Prop * 1000, Prop = NULL)
## gender Freq
## 1: Male 490
## 2: Female 510
Run Code Online (Sandbox Code Playgroud)
3)我们可以通过用折叠包中的ftransform替换transform来大大加快速度。
library(collapse)
dt[, ftransform(.SD, Freq = Prop * 1000, Prop = NULL)]
Run Code Online (Sandbox Code Playgroud)
4)同样
library(collapse)
ftransform(dt, Freq = Prop * 1000, Prop = NULL)
Run Code Online (Sandbox Code Playgroud)
使用问题中的数据,我们可以看到上面的 (4)(下面标记为 ex4),它使用来自塌陷的 ftransform 而不使用 [.data.table ,比上面的其他方法快得多。
library(collapse)
library(data.table)
library(microbenchmark)
microbenchmark(
ex1 = dt[, transform(.SD, Freq = Prop * 1000, Prop = NULL)],
ex2 = transform(dt, Freq = Prop * 1000, Prop = NULL),
ex3 = dt[, ftransform(.SD, Freq = Prop * 1000, Prop = NULL)],
ex4 = ftransform(dt, Freq = Prop * 1000, Prop = NULL)
)
Unit: microseconds
expr min lq mean median uq max neval cld
ex1 1847.601 1927.402 2046.04098 2015.4015 2093.251 2706.200 100 d
ex2 959.700 1000.701 1074.93098 1046.1510 1122.601 1606.201 100 b
ex3 1048.201 1090.351 1139.57598 1121.6005 1174.201 1381.602 100 c
ex4 68.401 85.551 93.08802 89.2515 100.551 168.400 100 a
Run Code Online (Sandbox Code Playgroud)