我想在一列中的一個的cumsum突破期間將一行分成兩個(或多個)行。 是否有任何優雅的方式來執行這樣的特定行爆炸使用data.table? 請不要關注cumsum(我使用的順序是從最近排到最早排的cumsum),嚴格來說,我想從下面的代碼轉換dt到rdt。R用行爆發的data.table轉換
# current data
dt <- data.table(
time_id = 101:110,
desc = c('asd','qwe','xyz','qwe','qwe','xyz','asd','asd','qwe','asd'),
value = c(5.5,3.5,14,0.7,6,5.5,9.3,29.8,4,7.2)
)
dt[, cum_value_from_now := rev(cumsum(rev(value)))]
period_width <- 10
dt[, value_period := ceiling(cum_value_from_now/period_width)*period_width]
dt
# expected result
rdt <- data.table(
time_id = c(101,102,103,103,104,105,105,106,107,107,108,108,108,108,109,109,110),
desc = c('asd','qwe','xyz','xyz','qwe','qwe','qwe','xyz','asd','asd','asd','asd','asd','asd','qwe','qwe','asd'),
value = c(5.5,3.5,6.5,7.5,0.7,1.8,4.2,5.5,0.3,9,1,10,10,8.8,1.2,2.8,7.2)
)[, cum_value_from_now := rev(cumsum(rev(value)))][, value_period := ceiling(cum_value_from_now/period_width)*period_width]
rdt
# validation
all.equal(
dt[,list(time_id,desc,value)],
rdt[,list(value = sum(value)), by=c('time_id','desc')]
)
編輯:我意識到我的問題是沒有很好地解釋我想執行的轉變。爲了更好地理解打破期間含義請看看我的rdt
cum_value_from_now
值從最後到第一。每個value_period
完全由cumsum
填充,value
,value
的其餘部分作爲新行生成(如果value
足夠大,則它生成多行)以適應下一個時期。謝謝
你是什麼意思的「打破時期」?對我們有些同情:使用一個矩陣,沒有'data.table'操作和期望的結果發佈一個小的,可重現的例子。同樣有用:告訴我們這個功能的重點是什麼,因爲實現最終目標可能有一種更簡單的方法。 –
「打破期間」最好由'value_period'變量定義。它是一種分組變量,在這個例子中,用'10'分組cumsum。至於「矩陣」的例子,我已經很久沒有使用矩陣了,我記得它可能無法在矩陣中混合數據類型。在我真正的'data.table'中,我還使用了更復雜的數據類型,因此將其轉換爲矩陣更加困難。重點是將適合兩個(或更多)時間段的行拆分成多個行,這些行將聚合到源行 - 如驗證步驟中那樣。 – jangorecki