R data.table 计算组中每个成员的子集向量函数

R data.table calculate function on subset vector for each member of group

我有一个数据 table 与

非常相似
set.seed(1)

dt<-data.table(med=sample(letters,50,T),
    diag=sample(LETTERS[1:7],50,T),
    val=sample(1:100,50,F))

我想计算任何 val 大于 val 的相同 diag 的概率,并将其分配给 table 的新列,说 prob(我知道概率不一定是正常的。我可以接受这种情况)。

我可以用 for 循环来完成:

for (i in 1:50){
    dg<-dt[i,diag]
    vl<-dt[i,val]
    dt$prob[i]<-pnorm(vl,
                      mean(dt[diag==dg,val]),
                      sd(dt[diag==dg,val]),
                      lower.tail = F)
}

但我的数据相当大(dt 大约有 800k 行,diag 上有大约 2k 级),所以我想矢量化而不是循环。

我试过了

dt[,
   .(lapply(.SD,function(x) 
                pnorm(x[1],
                mean(x),
                sd(x),
                lower.tail = F))),
   by=diag,
   .SDcols="val"]

当然,按 diag 分组只产生一种概率,因此用处不大。 我也试过

dt[,
   .(lapply(.SD,function(x) 
                pnorm(x[1],
                mean(x),
                sd(x),
                lower.tail = F))),
   by=.EACHI,
   .SDcols="val"]

但是它产生了一个错误:

Error in `[.data.table`(dt, , .(lapply(.SD, function(x) pnorm(x[1], mean(x),  : 
  logicial error. i is not data.table, but mult='all' and 'by'=.EACHI

通过矢量化生成所需结果的代码是什么?

因为我正在适应 data.tables,所以我更喜欢使用该包的解决方案,但是我绝对愿意接受任何其他解决方案来源(plyr、dplyr、等)。

谢谢,

这是一个dplyr解决方案:

dt %>% group_by(diag) %>% 
       mutate(prob = pnorm(val, mean(val), sd(val), lower.tail = FALSE))

data.table中:

dt[, prob2 := pnorm(val, mean(val), sd(val), lower.tail=FALSE), by=diag]

似乎符合您的要求:

head(dt)
#   med diag val       prob      prob2
#1:   p    E  91 0.04713131 0.04713131
#2:   f    E   3 0.92991675 0.92991675
#3:   o    B  26 0.83792988 0.83792988
#4:   t    C  38 0.70877125 0.70877125
#5:   g    E  71 0.16909178 0.16909178
#6:   i    E  25 0.75428819 0.75428819