[英]How to apply a function row-wise having if-else condition using data.table?
[英]Row-wise cumulative product on large data.table benchmarking
假設我有一個大的 data.table,大約有 1000 列和 100,000 行,如下所示:
dt <- data.table(col1 = runif(10^4))
for (i in 2:10^3) set(dt, j = paste('col', as.character(i), sep = ''), value = dt[[i-1]] * 0.95^(i-1))
將這些視為代表“每日死亡率”。 我想計算每月的存活率,所以我有以下代碼塊:
dt[, paste0('surv_rate_', 1:10^3) := Reduce('*', (1-dt[, paste0('col', 1:10^3)])^30, accumulate = T)]
我無法找到如上所示的行累積產品的任何基准測試。
您能想到以 data.table 方式執行此操作的任何更好/更清潔/更快的方法嗎?
(我也想到了as.data.table(t(cumprod(t(dt)))
但這似乎永遠需要這個大小的表)
正如評論中提到的,另一種可能的解決方案是沿行使用apply
:
res1 <-
copy(dt)[, paste0('surv_rate_', 1:10^3) := transpose(apply((1-.SD)^30,1,cumprod,simplify=F))]
res2 <- copy(dt)[, paste0('surv_rate_', 1:10^3) := Reduce('*', (1-dt[, paste0('col', 1:10^3)])^30, accumulate = T)]
all.equal(res1,res2)
[1] TRUE
但是,您的解決方案仍然快 30%:
Unit: milliseconds
expr min
copy(dt)[, `:=`(paste0("surv_rate_", 1:10^3), transpose(apply((1-.SD)^30, 1, cumprod, simplify = F)))] 1011.7095
copy(dt)[, `:=`(paste0("surv_rate_", 1:10^3), Reduce("*", (1-dt[, paste0("col", 1:10^3)])^30, accumulate = T))] 793.5415
lq mean median uq max neval
1246.993 1743.854 1546.797 2119.166 2772.646 10
1046.194 1314.569 1249.636 1405.414 2496.858 10
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.