简体   繁体   中英

Column-specific arguments to lapply in data.table .SD when applying rbinom

I have a data.table for which I want to add columns of random binomial numbers based on one column as number of trials and multiple probabilities based on other columns:

require(data.table)
DT = data.table(
  ID = letters[sample.int(26,10, replace = T)],
  Quantity=as.integer(100*runif(10))
)

prob.vecs <- LETTERS[1:5]
DT[,(prob.vecs):=0]
set.seed(123) 
DT[,(prob.vecs):=lapply(.SD, function(x){runif(.N,0,0.2)}), .SDcols=prob.vecs]
DT




ID Quantity          A           B          C           D          E
1:  b       66 0.05751550 0.191366669 0.17790786 0.192604847 0.02856000
2:  l        9 0.15766103 0.090666831 0.13856068 0.180459809 0.08290927
3:  u       38 0.08179538 0.135514127 0.12810136 0.138141056 0.08274487
4:  d       27 0.17660348 0.114526680 0.19885396 0.159093484 0.07376909
5:  o       81 0.18809346 0.020584937 0.13114116 0.004922737 0.03048895
6:  f       44 0.00911130 0.179964994 0.14170609 0.095559194 0.02776121
7:  d       81 0.10562110 0.049217547 0.10881320 0.151691908 0.04660682
8:  t       81 0.17848381 0.008411907 0.11882840 0.043281587 0.09319249
9:  x       79 0.11028700 0.065584144 0.05783195 0.063636202 0.05319453
10: j       43 0.09132295 0.190900730 0.02942273 0.046325157 0.17156554

Now I want to add five columns Quantity_A Quantity_B Quantity_C Quantity_D Quantity_E

which apply the rbinom with the correspoding probability and quantity from the second column. So for example the first entry for Quantity_A would be:

set.seed(741)
sum(rbinom(66,1,0.05751550))
> 2

This problem seems very similar to this post: How do I pass column-specific arguments to lapply in data.table .SD? but I cannot seem to make it work. My try:

DT[,(paste0("Quantity_", prob.vecs)):=  mapply(function(x, Quantity){sum(rbinom(Quantity, 1 , x))}, .SD), .SDcols = prob.vecs]

Error in rbinom(Quantity, 1, x) : argument "Quantity" is missing, with no default

Any ideas?

I seemed to have found a work-around, though I am not quite sure why this works (probably has something to do with the function rbinom not beeing vectorized in both arguments):

first define an index:

DT[,Index:=.I]

and then do it by index:

 DT[,(paste0("Quantity_", prob.vecs)):= lapply(.SD,function(x){sum(rbinom(Quantity, 1 , x))}), .SDcols = prob.vecs, by=Index]
set.seed(789) 

    ID Quantity          A           B          C           D          E Index Quantity_A Quantity_B Quantity_C Quantity_D Quantity_E
 1:  c       37 0.05751550 0.191366669 0.17790786 0.192604847 0.02856000     1          0          4          7          8          0
 2:  c       51 0.15766103 0.090666831 0.13856068 0.180459809 0.08290927     2          3          5          9         19          3
 3:  r        7 0.08179538 0.135514127 0.12810136 0.138141056 0.08274487     3          0          0          2          2          0
 4:  v       53 0.17660348 0.114526680 0.19885396 0.159093484 0.07376909     4          8          4         16         12          3
 5:  d       96 0.18809346 0.020584937 0.13114116 0.004922737 0.03048895     5         17          3         12          0          4
 6:  u       52 0.00911130 0.179964994 0.14170609 0.095559194 0.02776121     6          1          3          8          6          0
 7:  m       43 0.10562110 0.049217547 0.10881320 0.151691908 0.04660682     7          6          1          7          6          2
 8:  z        3 0.17848381 0.008411907 0.11882840 0.043281587 0.09319249     8          1          0          2          1          1
 9:  m        3 0.11028700 0.065584144 0.05783195 0.063636202 0.05319453     9          1          0          0          0          0
10:  o        4 0.09132295 0.190900730 0.02942273 0.046325157 0.17156554    10          0          0          0          0          0

numbers look about right to me

If someone finds a solution without the index would still be appreciated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM