R-对data.table中的多个列应用diff()函数或等效的自定义函数

R-对data.table中的多个列应用diff()函数或等效的自定义函数,r,data.table,R,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

当前有一个大致如下的
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
。该表通过设置键(dt,ID,Date)排序。我想计算每个ID中每个数值变量的滞后差

在我的数据中,我提取了如下向量中的数值列

cols <- c("Var3", "Var4")
cols_indx <- c(5:6) 
在我的数据上,none起作用并导致r[i1]-r[-length(r):-(length(r)-lag+1L)]:二进制运算符的非数字参数。我似乎不知道是什么导致了这一点,尤其是因为我在这段代码中没有看到任何二进制运算符

然而,一旦我无条件地声明了colname或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

i错误似乎是因为
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
df%>%group\u by(ID)%>%
变异(跨越(cols,~c(NA,diff(.)),.names=“{.col}\u diff”))
#一个tibble:8x8
#组别:ID[2]
ID日期Var1 Var2 Var3 Var4 Var3_diff Var4_diff
1 1 2020-03-01 AB A33 250 12 NA
2 1 2020-04-01 B B25 NA 14 NA 2
3 1 2020-05-01 AB A44 270 20 NA 6
412020-06-01空调C33913-261-7
522019-09-01 X C55280 11不适用
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

我会在几分钟后试一试。谢谢你的建议!你能很快澄清一下diff函数中的
~c(NA,…)
()
参数到底是做什么的吗?输出完全是我需要的,所以是:)对于
NA
我在答案中添加了解释。请参见编辑。关于整洁的
,它实际上是编写不可见函数的简写,其中
~
替换
函数(x)
替换
x
到处都是,这很整洁。对于R来说还是比较新的,所以这在将来可能会有所帮助。非常感谢阿尼尔!因此,如果我要计算滞后差,比如在第2个周期,我就需要添加
~c(NA,NA,diff(.))
?我已经注意到了这种行为,但到目前为止还没有找到一种方法来对付它。谢天谢地,我有一个存储各种感兴趣的数值变量的大型数据集,我需要将它们(在我的实际数据中)滞后1、2、4和8个季度,以获得回归设置的滞后差异。不幸的是,并非每个
ID
的所有数据点都可用,因此NAs不可避免地会通过数据传播。无论如何,我计算了我的季度数据集在所述期间(3M、6M、12M、24M)的滞后差异,然后通过滚动联接将此data.table中的数据联接到我的主数据集。
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