将函数应用于data.table中的矢量化列值 请考虑这个 library(data.table) mydt <- data.table(id = 1:100, p1 = sample(seq(0,1,length.out=1000),100)) mydt$p2 <- 1 - mydt$p1
这很有效将函数应用于data.table中的矢量化列值 请考虑这个 library(data.table) mydt <- data.table(id = 1:100, p1 = sample(seq(0,1,length.out=1000),100)) mydt$p2 <- 1 - mydt$p1,r,data.table,R,Data.table,这很有效 mydt$outcome <- apply(mydt[,2:3], 1, myFun) sample中的prob参数需要向量。要将myFun应用于每一行,可以使用by=1:nrow(mydt)或by=1:mydt[,.N] mydt[, chosen := myFun(c(p1, p2)), by=1:nrow(mydt)] @Roland使用了rbinom,向他致敬。他为这次伯努利试验设计的矢量化版本要快得多 > system.time(mydt[, chosen
mydt$outcome <- apply(mydt[,2:3], 1, myFun)
sample
中的prob
参数需要向量。要将myFun
应用于每一行,可以使用by=1:nrow(mydt)
或by=1:mydt[,.N]
mydt[, chosen := myFun(c(p1, p2)), by=1:nrow(mydt)]
@Roland使用了
rbinom
,向他致敬。他为这次伯努利试验设计的矢量化版本要快得多
> system.time(mydt[, chosen := myFun(c(p1, p2)), by=1:nrow(mydt)])
user system elapsed
4.82 0.00 4.86
> system.time(mydt[, outcome2 := rbinom(.N, 1, p2) + 1])
user system elapsed
0.05 0.02 0.06
计时中使用的数据:
library(data.table)
set.seed(0L)
m <- 1e6
mydt <- data.table(id = 1:m, p1 = runif(m))[, p2 := 1 - p1]
myFun <- function(x) sample(c(1,2), 1, prob = x)
库(data.table)
种子集(0升)
sample
中的mprob
参数需要一个向量。要将myFun
应用于每一行,可以使用by=1:nrow(mydt)
或by=1:mydt[,.N]
mydt[, chosen := myFun(c(p1, p2)), by=1:nrow(mydt)]
@Roland使用了rbinom
,向他致敬。他为这次伯努利试验设计的矢量化版本要快得多
> system.time(mydt[, chosen := myFun(c(p1, p2)), by=1:nrow(mydt)])
user system elapsed
4.82 0.00 4.86
> system.time(mydt[, outcome2 := rbinom(.N, 1, p2) + 1])
user system elapsed
0.05 0.02 0.06
计时中使用的数据:
library(data.table)
set.seed(0L)
m <- 1e6
mydt <- data.table(id = 1:m, p1 = runif(m))[, p2 := 1 - p1]
myFun <- function(x) sample(c(1,2), 1, prob = x)
库(data.table)
种子集(0升)
m如果您想从data.table
中获益,我建议您坚持使用data.table
语法。因此,要在mydt
中创建一个新列p2
,如果您想从data.table
中获益,建议使用data.table
语法,而不是mydt$p2。因此,要在mydt
中创建一个新列p2
,请使用mydt[,p2:=1-p1]
而不是mydt$p2,这仍然是一个缓慢的循环。我认为,mydt[,outcome 2:=rbinom(.N,1,p2)+1]
也应该这样做,但即使在设置种子时也不能完全复制结果。谢谢,@Roland。你的矢量化方法肯定会更快。我认为即使是播种,结果也无法与之匹敌。为什么不呢?我本以为他们会匹配的。例如,set.seed(42);这仍然是一个缓慢的循环。我认为,mydt[,outcome 2:=rbinom(.N,1,p2)+1]
也应该这样做,但即使在设置种子时也不能完全复制结果。谢谢,@Roland。你的矢量化方法肯定会更快。我认为即使是播种,结果也无法与之匹敌。为什么不呢?我本以为他们会匹配的。例如,set.seed(42);x