2015-09-06 106 views
0

我試圖解決data.table中的一個問題,它需要我使用預測的下一步中預測的值。使用預測值在data.table中預測

我有這樣的數據設置,NA行生成準備接收預測。每個NA是由當前參數之前它的價值乘以

library(data.table) 

dt <- data.table(
    date = as.Date(paste(rep(c(2015, 2016), each = 12, times = 2), 1:12, 1, sep = "-")), 
    val = c(rnorm(12, 50, 5), rep(NA, 12)), 
    param1 = runif(48), 
    cat = rep(c("a", "b"), each = 24) 
) 

我不能做這種方式

dt[, { 
    dt_in <- .SD 

    lapply(dt_in[year(date) > 2015, date], function(d){ 
    dt_sub <- dt_in[date <= d] 
    pred <- dt_sub[.N-1, val] * dt_sub[.N, param1] 
    dt_in[date == d, val := pred] 
    }) 
} , by = cat] 

至於試圖更新中.SD {}給我「 .SD被鎖定...'錯誤。我目前的解決方案涉及打破data.table成一個列表,並通過排

# Create a list of data.tables, one for each category 
break_list <- lapply(dt[, unique(cat)], function(c){ 
    dt[cat == c] 
}) 

l_out <- lapply(break_list, function(dt_in){ 
# Select the dates requiring prediction 
    lapply(dt_in[year(date) > 2015, date], function(d){ 
    # Subset by date 
    dt_sub <- dt_in[date <= d] 
    # Prediciton = value from the second to last row * parameter in the last row 
    pred <- dt_sub[.N-1, val] * dt_sub[.N, param1] 
    # Update data.table 
    dt_in[date == d, val := pred] 
    }) 
    dt_in 
}) 

dt_out <- rbindlist(l_out) 

這工作,並給了我希望的解決方案更新每個列表項的行,但它可能會很慢,感覺就像我已經打破了所有的data.table規則。有沒有更好的辦法?

+2

這是相當多的代碼(這是很好的),但很少解釋你正在努力完成什麼。你能告訴我們期望的結果應該是什麼樣子(有解釋)。 –

+0

Richard,在'dt'中,您將看到需要用預測替換的NAs。在dt_out中,您將找到所需的結果。大衛,我已經更新了一些信息。 –

+0

@DavidArenburg不正確 - 需要使用'dt_in < - copy(.SD)'(通過引用獲取data.table副本 - 如果a被鎖定,則b <-a將是相同的鎖定表)。然而,我幾乎可以肯定,一個錯誤的道路做這樣的事情...... –

回答

1

您正在尋找使用從先前迭代中更新的行計算出的值迭代更新data.table的行。雖然通常更好地找到使問題更新獨立的問題的明確表達式,並且在您的情況下可以使用持有cumprodparam1和滾動連接(dt[dt[...], ..., roll=TRUE])的幫助列,我將演示如何執行迭代更新data.table有效利用data.table::set,因爲前者並不總是很容易/可能:

setkey(dt, cat, date) # sort by cat first then by date in have the reference value used for each calculation in the row above 
val_col_nr <- which(colnames(dt)=="val") # set requires a column number 
dt[is.na(val), # we want to compute new values for val where val currently is NA 
    # .I is a vector the row numbers (in dt) of each row in .SD 
    for (ii in .I) set(dt, i=ii, j=val_col_nr, value=dt[ii,param1]*dt[ii-1L,val]), 
    by=cat] # for every 'cat' 

您可以使用identical(dt, setkey(dt_out,cat,date))檢查結果。

請注意,使用基函數名稱(在您的情況下爲cat)作爲變量名稱(即使在不同的名稱空間中)通常也是一個壞主意。

+0

我忘了'貓'是一個基本功能 - 感謝提醒 –