簡體   English   中英

使用 data.table 創建滯后列

[英]Create lagged columns using data.table

背景:
假設我有這個代碼

library(data.table)

#reproducibility
set.seed(45L)

#make table
dt <- data.table(V1=c(1L,2L),
                 V2=LETTERS[1:3],
                 V3=round(rnorm(4),4),
                 V4 = 1:12)
dt

我得到

> dt
    V1 V2      V3 V4
 1:  1  A  0.3408  1
 2:  2  B -0.7033  2
 3:  1  C -0.3795  3
 4:  2  A -0.7460  4
 5:  1  B  0.3408  5
 6:  2  C -0.7033  6
 7:  1  A -0.3795  7
 8:  2  B -0.7460  8
 9:  1  C  0.3408  9
10:  2  A -0.7033 10
11:  1  B -0.3795 11
12:  2  C -0.7460 12

我想追加創建 10 列 V3 的滯后。

題:
有沒有辦法在“數據表”范式中做到這一點。

更多細節:
如果它是一個 data.frame 那么我可以做一個循環。

dt <- as.data.frame(dt)


for(i in 1:10){
     dt <- cbind(dt, shift(x = dt[, 3], 
                           n = i, 
                           fill = NA, 
                           type = "lag"))
     names(dt)[ncol(dt)] <- sprintf("lag_%06d",i)
}

dt

我得到:

> dt
   V1 V2      V3 V4 lag_000001 lag_000002 lag_000003 lag_000004 lag_000005 lag_000006 lag_000007 lag_000008 lag_000009 lag_000010
1   1  A  0.3408  1         NA         NA         NA         NA         NA         NA         NA         NA         NA         NA
2   2  B -0.7033  2     0.3408         NA         NA         NA         NA         NA         NA         NA         NA         NA
3   1  C -0.3795  3    -0.7033     0.3408         NA         NA         NA         NA         NA         NA         NA         NA
4   2  A -0.7460  4    -0.3795    -0.7033     0.3408         NA         NA         NA         NA         NA         NA         NA
5   1  B  0.3408  5    -0.7460    -0.3795    -0.7033     0.3408         NA         NA         NA         NA         NA         NA
6   2  C -0.7033  6     0.3408    -0.7460    -0.3795    -0.7033     0.3408         NA         NA         NA         NA         NA
7   1  A -0.3795  7    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408         NA         NA         NA         NA
8   2  B -0.7460  8    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408         NA         NA         NA
9   1  C  0.3408  9    -0.7460    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408         NA         NA
10  2  A -0.7033 10     0.3408    -0.7460    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408         NA
11  1  B -0.3795 11    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408
12  2  C -0.7460 12    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033     0.3408    -0.7460    -0.3795    -0.7033

必須有更優雅的方式。 可以更快、更有效地處理更大數據的東西。

現在,如果我想首先這樣做,在 V3 列上,然后在 V4 列上制作 10 個滯后,而不預設它們的名稱,該怎么辦? 我可以簡單地嵌套 for 循環,但我再次懷疑 data.table 有一些好的(很棒?)可以提供。

是的, shift考慮了這種類型的用戶需求。 當用於shift參數n是向量時, shift將為n每個移位返回一個列表:

dt[, sprintf("V3_lag_%06d", 1:10) := shift(V3, 1:10, type = 'lag')]
dt[, sprintf("V4_lag_%06d", 1:10) := shift(V4, 1:10, type = 'lag')]

#     V1 V2      V3 V4 V3_lag_000001 V3_lag_000002 V3_lag_000003 V3_lag_000004 V3_lag_000005
#  1:  1  A  1.2322  1            NA            NA            NA            NA            NA
# 2:  2  B  1.6094  2        1.2322            NA            NA            NA            NA
# 3:  1  C  0.4016  3        1.6094        1.2322            NA            NA            NA
# 4:  2  A -0.2730  4        0.4016        1.6094        1.2322            NA            NA
# 5:  1  B  1.2322  5       -0.2730        0.4016        1.6094        1.2322            NA
# 6:  2  C  1.6094  6        1.2322       -0.2730        0.4016        1.6094        1.2322
# 7:  1  A  0.4016  7        1.6094        1.2322       -0.2730        0.4016        1.6094
# 8:  2  B -0.2730  8        0.4016        1.6094        1.2322       -0.2730        0.4016
# 9:  1  C  1.2322  9       -0.2730        0.4016        1.6094        1.2322       -0.2730
# 10:  2  A  1.6094 10        1.2322       -0.2730        0.4016        1.6094        1.2322
# 11:  1  B  0.4016 11        1.6094        1.2322       -0.2730        0.4016        1.6094
# 12:  2  C -0.2730 12        0.4016        1.6094        1.2322       -0.2730        0.4016
# V3_lag_000006 V3_lag_000007 V3_lag_000008 V3_lag_000009 V3_lag_000010 V4_lag_000001
# 1:            NA            NA            NA            NA            NA            NA
# 2:            NA            NA            NA            NA            NA             1
# 3:            NA            NA            NA            NA            NA             2
# 4:            NA            NA            NA            NA            NA             3
# 5:            NA            NA            NA            NA            NA             4
# 6:            NA            NA            NA            NA            NA             5
# 7:        1.2322            NA            NA            NA            NA             6
# 8:        1.6094        1.2322            NA            NA            NA             7
# 9:        0.4016        1.6094        1.2322            NA            NA             8
# 10:       -0.2730        0.4016        1.6094        1.2322            NA             9
# 11:        1.2322       -0.2730        0.4016        1.6094        1.2322            10
# 12:        1.6094        1.2322       -0.2730        0.4016        1.6094            11
# V4_lag_000002 V4_lag_000003 V4_lag_000004 V4_lag_000005 V4_lag_000006 V4_lag_000007
# 1:            NA            NA            NA            NA            NA            NA
# 2:            NA            NA            NA            NA            NA            NA
# 3:             1            NA            NA            NA            NA            NA
# 4:             2             1            NA            NA            NA            NA
# 5:             3             2             1            NA            NA            NA
# 6:             4             3             2             1            NA            NA
# 7:             5             4             3             2             1            NA
# 8:             6             5             4             3             2             1
# 9:             7             6             5             4             3             2
# 10:             8             7             6             5             4             3
# 11:             9             8             7             6             5             4
# 12:            10             9             8             7             6             5
# V4_lag_000008 V4_lag_000009 V4_lag_000010
# 1:            NA            NA            NA
# 2:            NA            NA            NA
# 3:            NA            NA            NA
# 4:            NA            NA            NA
# 5:            NA            NA            NA
# 6:            NA            NA            NA
# 7:            NA            NA            NA
# 8:            NA            NA            NA
# 9:             1            NA            NA
# 10:             2             1            NA
# 11:             3             2             1
# 12:             4             3             2

也可以在 1 個data.table調用中完成所有data.table 如果您需要很多列,這可能特別有用:

cols <- c("V3","V4")
dt[, (paste0("lag_",rep(cols, each = 10), "_", rep(1:10, times = length(cols)))) := 
            unlist(lapply(.SD, function(x) shift(x, 1:10, type = "lag")), recursive = F), .SDcols = cols]

paste0(...)代碼按照我們想要的方式設置列名,然后unlist(lapply(...))代碼按照我們想要的順序獲取每一列的滯后。 要查看每個工作原理,您可以單獨運行它們(如果運行unlist(lapply(...))您必須將dt[,c("V3","V4")] .SD.SD

dt[,1:9]
#    V1 V2      V3 V4 lag_V3_1 lag_V4_1 lag_V3_2 lag_V4_2 lag_V3_3
# 1:  1  A  0.3408  1       NA       NA       NA       NA       NA
# 2:  2  B -0.7033  2   0.3408        1       NA       NA       NA
# 3:  1  C -0.3795  3  -0.7033        2   0.3408        1       NA
# 4:  2  A -0.7460  4  -0.3795        3  -0.7033        2   0.3408
# 5:  1  B  0.3408  5  -0.7460        4  -0.3795        3  -0.7033
# 6:  2  C -0.7033  6   0.3408        5  -0.7460        4  -0.3795
# 7:  1  A -0.3795  7  -0.7033        6   0.3408        5  -0.7460
# 8:  2  B -0.7460  8  -0.3795        7  -0.7033        6   0.3408
# 9:  1  C  0.3408  9  -0.7460        8  -0.3795        7  -0.7033
#10:  2  A -0.7033 10   0.3408        9  -0.7460        8  -0.3795
#11:  1  B -0.3795 11  -0.7033       10   0.3408        9  -0.7460
#12:  2  C -0.7460 12  -0.3795       11  -0.7033       10   0.3408

Mike H. 的回答對我不起作用——我認為可能是由於 data.table 更新。 修改后的形式是:

lagcols <- c('test1','test2') #input column names

lagcols2<- paste0("lag",  #output column names
  rep(lag, times = length(lagcols)),'_',
  rep(lagcols, each = length(lag)))

lag <- c(1,2,10) #desired lags

dt[, (lagcols2) :=  shift(.SD, lag), by=id]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM