在處理大型資料集并應用使用 data.table 的多列作為輸入的函式時,我遇到了計算時間問題。這是一個簡化的示例:
require(data.table)
main_dt <- data.table(Start=(1:2), End=c(2,2))
lookup_dt <- data.table(Year = 1:3, Amount = c(10,20,30))
所以:
> main_dt
Start End
1: 1 2
2: 2 2
和
> lookup_dt
Year Amount
1: 1 10
2: 2 20
3: 3 30
我想要的是在 data.table main_dt中添加一列,其中包括Start和End之間的 Amounts of Years 的總和。所以像這樣,但是有一個參考錯誤。
main_dt[, Amount := lookup_dt[ Year >= start & Year <= end, sum(Amount)]]
Warning messages:
1: In Year >= Start : longer object length is not a multiple of shorter object length
2: In Year <= End : longer object length is not a multiple of shorter object length
如果金額僅取決于一個變數,我可以這樣做:
main_dt[, GreaterAmount := lapply(Start, function(x) return (lookup_dt[Year >= x, sum(Amount)]))]
要得到:
> main_dt
Start End Amount GreaterAmount
1: 1 2 30 60
2: 2 2 30 50
沒關系,但是
- 我需要應用一個實際上同時依賴于Start 和 End的函式
- 對每一行單獨應用一個函式會迅速減慢計算程序。將高度贊賞矢量化解決方案。
期待任何建議!
謝謝!馬庫斯
uj5u.com熱心網友回復:
首先,連接列應該是同一個類,所以我們可以轉換main_dt$End
為整數,main_df$Start
也可以轉換lookup_dt$Year
為數字。我會選擇第一個:
main_dt[, End := as.integer(End)]
main_dt
# Start End
# <int> <int>
# 1: 1 2
# 2: 2 2
從這里,我們可以做一個加入任務:
main_dt[, Amount := lookup_dt[.SD, sum(Amount), on = .(Year >= Start, Year <= End), by = .EACHI]$V1 ]
main_dt
# Start End Amount
# <int> <int> <num>
# 1: 1 2 30
# 2: 2 2 20
如果您對 有點熟悉data.table
,請注意.SD
referenced 實際上是 的內容main_dt
,因此實際上lookup_dt[.SD,...]
是"main_dt left join lookup_dt"。從那里開始,on=
應該是正常的,并且sum(Amount)
是您想要聚合的內容。這里引入的唯一新事物是 的使用by=.EACHI
,這可能會造成混淆;一些鏈接:
- https://rdatatable.gitlab.io/data.table/reference/special-symbols.html
- https://stackoverflow.com/a/27004566/3358272
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/494232.html
上一篇:r在資料框串列上應用函式