我希望转置一个时间序列数据集,以提供给一些机器学习算法。这是我想要做的一个例子,除了滞后的数量很大,我正在寻找一种更优雅的方式:
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
答案 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::lag
或data.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