将函数应用于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
中的m
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升)

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