用dplyr转置时间序列(用滞后变异)

时间:2016-05-10 01:58:45

标签: r dplyr

我希望转置一个时间序列数据集,以提供给一些机器学习算法。这是我想要做的一个例子,除了滞后的数量很大,我正在寻找一种更优雅的方式:

    set.seed(42)
data <- data.frame(time = 1:5, value = rnorm(5))
data
# time      value
# 1    1  1.3709584
# 2    2 -0.5646982
# 3    3  0.3631284
# 4    4  0.6328626
# 5    5  0.4042683
data %>%
  mutate(lag_1 = lag(value),
         lag_2 = lag(value, 2),
         lag_3 = lag(value, 3),
         lag_4 = lag(value, 4),
         lag_5 = lag(value, 5))
# time      value      lag_1      lag_2      lag_3    lag_4 lag_5
# 1    1  1.3709584         NA         NA         NA       NA    NA
# 2    2 -0.5646982  1.3709584         NA         NA       NA    NA
# 3    3  0.3631284 -0.5646982  1.3709584         NA       NA    NA
# 4    4  0.6328626  0.3631284 -0.5646982  1.3709584       NA    NA
# 5    5  0.4042683  0.6328626  0.3631284 -0.5646982 1.370958    NA

4 个答案:

答案 0 :(得分:4)

您可以更方便地使用data.table进行转换,因为来自shift的{​​{1}}允许参数data.table成为向量,而n函数位于lag没有。

dplyr

要更具体地了解library(data.table) > setDT(data)[, paste("lag", 1:5, sep = "_") := shift(value, 1:5)] > data time value lag_1 lag_2 lag_3 lag_4 lag_5 1: 1 -1.4162466 NA NA NA NA NA 2: 2 -0.2366333 -1.4162466 NA NA NA NA 3: 3 0.5146632 -0.2366333 -1.4162466 NA NA NA 4: 4 1.9243923 0.5146632 -0.2366333 -1.4162466 NA NA 5: 5 1.6161165 1.9243923 0.5146632 -0.2366333 -1.416247 NA shift,以下是lag函数不允许您执行lag所做的事情的示例。

shift

答案 1 :(得分:1)

bind_cols可能比mutate更方便,因为使用向量化版本dplyr::lagdata.table::shift生成滞后数据框很容易:< / p>

data %>% bind_cols(setNames(data.frame(Vectorize(lag, 'n')(.$value, 1:5)), 
                            paste0('lag_', 1:5)))
# Source: local data frame [5 x 7]
# 
#    time      value      lag_1      lag_2      lag_3    lag_4 lag_5
#   (int)      (dbl)      (dbl)      (dbl)      (dbl)    (dbl) (dbl)
# 1     1  1.3709584         NA         NA         NA       NA    NA
# 2     2 -0.5646982  1.3709584         NA         NA       NA    NA
# 3     3  0.3631284 -0.5646982  1.3709584         NA       NA    NA
# 4     4  0.6328626  0.3631284 -0.5646982  1.3709584       NA    NA
# 5     5  0.4042683  0.6328626  0.3631284 -0.5646982 1.370958    NA

data %>% bind_cols(data.frame(shift(.$value, 1:5, give.names = TRUE)))
# Source: local data frame [5 x 7]
# 
#    time      value   V1_lag_1   V1_lag_2   V1_lag_3 V1_lag_4 V1_lag_5
#   (int)      (dbl)      (dbl)      (dbl)      (dbl)    (dbl)    (dbl)
# 1     1  1.3709584         NA         NA         NA       NA       NA
# 2     2 -0.5646982  1.3709584         NA         NA       NA       NA
# 3     3  0.3631284 -0.5646982  1.3709584         NA       NA       NA
# 4     4  0.6328626  0.3631284 -0.5646982  1.3709584       NA       NA
# 5     5  0.4042683  0.6328626  0.3631284 -0.5646982 1.370958       NA

或者,您可以使用普通的data.frame代替:

data.frame(data, shift(data$value, 1:5, give.names = TRUE))

答案 2 :(得分:0)

可以使用base R通过lapply完成此操作。我们使用k遍历lapply并将输出分配到&#39;数据&#39;中的新列。

data[paste("lag", 1:5, sep="_")] <- lapply(1:5, function(i) lag(data$value, i))
data
#  time      value      lag_1      lag_2      lag_3    lag_4 lag_5
#1    1  1.3709584         NA         NA         NA       NA    NA
#2    2 -0.5646982  1.3709584         NA         NA       NA    NA
#3    3  0.3631284 -0.5646982  1.3709584         NA       NA    NA
#4    4  0.6328626  0.3631284 -0.5646982  1.3709584       NA    NA
#5    5  0.4042683  0.6328626  0.3631284 -0.5646982 1.370958    NA

答案 3 :(得分:0)

我有同样的问题。我就这样做了:

set.seed(42)

data <- data.frame(time = 1:5, value = rnorm(5))

lags<-5

lags.tmp <-funs_(sapply(1:lags, function(x) paste0("lag(.,",x,")")))
names(lags.tmp)<-sapply(1:lags, function(x) paste0("lag_",x))

data %>%
  mutate_at(vars(value),.funs=lags.tmp)
#  time      value      lag_1      lag_2      lag_3    lag_4 lag_5
#1    1  1.3709584         NA         NA         NA       NA    NA
#2    2 -0.5646982  1.3709584         NA         NA       NA    NA
#3    3  0.3631284 -0.5646982  1.3709584         NA       NA    NA
#4    4  0.6328626  0.3631284 -0.5646982  1.3709584       NA    NA
#5    5  0.4042683  0.6328626  0.3631284 -0.5646982 1.370958    NA