r - R - 在 data.table 中的多个列上应用 diff() 函数或等效的自定义函数
问题描述
目前有一个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
和一些对应的变量。有些是 type char
,有些是 type numeric
。该表已排序,setkey(dt, ID, Date)
我想计算每个 ID 中每个数字变量的滞后差。
在我的数据中,我在看起来像这样的向量中提取了数字列。
cols <- c("Var3", "Var4")
cols_indx <- c(5:6)
然后,我想将具有数字变量滞后差异的新列添加Var5
到Var6
我的 data.tabledt
中。
我尝试:
# 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。我似乎无法弄清楚是什么原因造成的,尤其是因为我在这段代码中的任何地方都没有看到二进制运算符。
但是,一旦我明确说明 colnames 或 col 索引,一切正常。这是为什么?在我的情况下,我需要移动一个超过 250 列的长 data.table,然后计算滞后差异或所有这些列以及多个滞后间隔的所有列。手动定义所有选定的列是不可管理的。我在这里想念什么?
# 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
使用自定义函数时,都会抛出类似的错误。
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
推荐阅读
- c# - 用于更改 Azure Active Directory 用户个人资料图片的 REST API
- python - 使用列表检索字符串值
- javascript - 如何使用从另一个 websocket 获取的数据创建 websocket
- php - Laravel 6.x 本地高级字符串搜索
- macos - macOS命令行中双引号的影响?
- javascript - Stackblitz:将编译目标更改为 es6
- c# - 使用正则表达式检查文件名字符串是否包含给定的子字符串
- python - 多处理时 Pytorch 推断 CUDA 内存不足
- python - 使用 xattr 显示 macOS 文件注释
- matlab - Writematrix 命令在 MATLAB 中不起作用