Reputation: 443
I have the following data.table
object:
USER active rate day # of elements by hour
4q7C0o 1 1.48 1 c(0, 0, 0, 0, 0, 0, 5, 98, 167, 211, 246)
2BrKY63 1 0.5 3 c(0, 0, 0, 0, 0, 0, 0, 5, 15, 24, 89, 187)
3drUy6I 1 2.58 5 c(0, 0, 0, 0, 0, 0, 0, 0, 1, 112, 265, 309)
G5ALtO 1 1.1 7 c(0, 0, 0, 0, 0, 0, 0, 2, 20, 153, 170)
Where each element of the column # of elements by hour
is a list with varying length. I would like to apply the function pexp()
to each element of each list (ex. pexp(0, rate = 1.48) to the first element of the first list and pexp(246, rate = 1.48) to the last element of the first list) and if a value less than 'x' occurs then it is displayed in a new column. Something like :
DT[, ifelse(any(lapply( of elements by hour, pexp, rate = rate) < x), 'no.usable','usable' ) ,]
However I don't know how could this be done in a short way in data.table
.
Upvotes: 3
Views: 166
Reputation: 34703
pexp
is the exponential density, which is monotonic & easily invertible. Your condition is satisfied for rate l if:
# elem > 1 / rate * log(rate / x)
Hence we only need to look at the largest number of each list and check the condition there.
With that in mind, we can do:
DT[ , fifelse(sapply(`# elem`, max) > 1/rate*log(rate/x), 'no.usable', 'usable')]
Upvotes: 6
Reputation: 887078
Here is one option with Map
where we apply the pexp
on each element of "# of elements by hour"
with the corresponding 'rate' column value
DT[, c('usable', 'no.usable')[unlist(Map(function(x, y)
any(pexp(x, rate = y) < x)) `# of elements by hour`, rate)) + 1]]
Or with fifelse
DT[, fifelse(unlist(Map(function(x, y)
any(pexp(x, rate = y) < x)) `# of elements by hour`, rate)),
'no.usable', 'usable')]
Upvotes: 2