![](/img/trans.png)
[英]R data.table way to create summary statistics table with self-defined function
[英]R - apply diff() function or equivalent self-defined function on multiple columns in a data.table
目前有一個data.table
大致如下所示:
ID Date Var1 Var2 Var3 Var4
1 2020-03-01 AB A33 250 12
1 2020-04-01 B B25 NA 14
1 2020-05-01 AB A44 270 20
1 2020-06-01 AC C33 9 13
2 2019-09-01 X C55 280 11
2 2019-10-01 K C89 120 12
2 2019-11-01 A C89 320 NA
2 2019-12-01 AB A88 200 25
該數據表存儲了密鑰ID
和一些對應的變量。 有些是char
類型,有些是numeric
類型。 該表使用setkey(dt, ID, Date)
進行排序我想計算每個 ID 中每個數字變量的滯后差。
在我的數據中,我在看起來像這樣的向量中提取了數字列。
cols <- c("Var3", "Var4")
cols_indx <- c(5:6)
然后,我想將具有數值變量Var5
和Var6
的滯后差異的新列添加到我的 data.table dt
中。
我嘗試:
# Doesn't work
as.data.frame(lapply(dt[ , cols, with = FALSE], diff, lag = 1))
as.data.frame(lapply(dt[ , cols_indx, with = FALSE], diff, lag = 1))
as.data.frame(lapply(dt[ , .SD, .SDcols = cols], diff, lag = 1))
as.data.frame(lapply(dt[ , .SD, .SDcols = cols_indx], diff, lag = 1))
在我的數據中沒有一個有效並導致r[i1] - r[-length(r):-(length(r) - lag + 1L)]: non-numeric argument for binary operator 。 我似乎無法弄清楚是什么原因造成的,尤其是因為我在這段代碼中的任何地方都沒有看到二進制運算符。
但是,一旦我明確 state 或者 colnames 或 col 索引,一切正常。 這是為什么? 在我的情況下,我需要將長 data.table 與 > 250 列一起移動,然后計算滯后差異或所有這些列以及多個滯后間隔的所有列。 手動定義所有選定的列是不可管理的。 我在這里想念什么?
# Works
as.data.frame(lapply(dt[ , 5:6], diff, lag = 1))
as.data.frame(lapply(financials.dt[ , c("Var4", "Var5")], diff, lag = 1))
此外,還缺少一個步驟。 我想計算每個組內的滯后差異(由ID
定義)。 當我嘗試diff
和自定義 function 時,都會拋出類似的錯誤。
i <- 1
lag_names_diff <- paste(cols, "Lag", i, "d", sep = "_")
dt[ , (lag_names_diff) := lapply(.SD, function(x) x - shift(x, (i), type = "lag")),
.SDcols = cols, by = ID]
# Error 1:
# r[i1] - r[-length(r):-(length(r) - lag + 1L)] : non-numeric argument for binary operator
# or
dt[ , (lag_names_diff) := lapply(.SD, diff, x = cols, lag = i, differences = 1),
.SDcols = cols, by = ID]
# Error 2:
# x - shift(x, (i), type = "lag") : non-numeric argument for binary operator
...一切都因錯誤消息而崩潰。 我似乎無法弄清楚是什么原因造成的。 非常感謝任何指針。
該錯誤似乎是因為diff(any_vector)
返回一個向量,但長度比any_vector
短。 看到這個
diff(1:5)
[1] 1 1 1 1
因此,如果要將diff
應用於表中的任何變量,則必須在結果中添加一個元素,無論是在結束時還是在開始時。 盡管我不確定您的預期結果,但我仍然假設這一點。 (我將NA
添加到結果向量的開頭。如果需要,您也可以添加0
。
library(dplyr)
df %>% mutate(across(cols, ~c(NA, diff(.)), .names = "{.col}_diff"))
ID Date Var1 Var2 Var3 Var4 Var3_diff Var4_diff
1 1 2020-03-01 AB A33 250 12 NA NA
2 1 2020-04-01 B B25 NA 14 NA 2
3 1 2020-05-01 AB A44 270 20 NA 6
4 1 2020-06-01 AC C33 9 13 -261 -7
5 2 2019-09-01 X C55 280 11 271 -2
6 2 2019-10-01 K C89 120 12 -160 1
7 2 2019-11-01 A C89 320 NA 200 NA
8 2 2019-12-01 AB A88 200 25 -120 NA
或者如果需要按ID
分組
df %>% group_by(ID) %>%
mutate(across(cols, ~c(NA, diff(.)), .names = "{.col}_diff"))
# A tibble: 8 x 8
# Groups: ID [2]
ID Date Var1 Var2 Var3 Var4 Var3_diff Var4_diff
<int> <chr> <chr> <chr> <int> <int> <int> <int>
1 1 2020-03-01 AB A33 250 12 NA NA
2 1 2020-04-01 B B25 NA 14 NA 2
3 1 2020-05-01 AB A44 270 20 NA 6
4 1 2020-06-01 AC C33 9 13 -261 -7
5 2 2019-09-01 X C55 280 11 NA NA
6 2 2019-10-01 K C89 120 12 -160 1
7 2 2019-11-01 A C89 320 NA 200 NA
8 2 2019-12-01 AB A88 200 25 -120 NA
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.