2016-05-11 94 views
1

我有20x1的数据框df,并添加了一个20x3的滞后变量矩阵。还想添加一个20x3的铅变量矩阵。我怎样才能做到这一点?非常感谢你。创建铅变量矩阵

df <- data.frame(Close = c(1221, 1220, 1220, 1217, 1216, 1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205)) 

n <- NROW(df$Close); m <- 3     #how many bars bck to check 
LagMatrixClose <- matrix(nrow = n, ncol = m) #pre-allocate 
LagMatrixClose <- matrix(unlist(data.table::shift(df$Close, 1L:m)), ncol=m) 
dimnames(LagMatrixClose) <- list(rownames(LagMatrixClose, do.NULL = FALSE, prefix = ""), 
           colnames(LagMatrixClose, do.NULL = FALSE, prefix = "LagC")) 
df <- cbind(df, LagMatrixClose) 

EDIT/UPDATE:以下代码添加铅变量的这种基质,但它采用的是for循环,我宁愿避免出于效率目的,因为这是将被施加到一个大的数据框架不仅创建3个主要变量,而且还创建数百个变量。有人可以考虑替代方案吗?

rowShift <- function(x, shiftLen = 1L) { 
    r <- (1L + shiftLen):(length(x) + shiftLen) 
    r[r<1] <- NA 
    return(x[r]) } 

n <- NROW(df$Close); m <- 3     #how many bars bck to check 
LeadMatrixClose <- matrix(nrow = n, ncol = m) #pre-allocate 
for(i in 1:3) { LeadMatrixClose[,i ] <- rowShift(df$Close,+i) } 
dimnames(LeadMatrixClose) <- list(rownames(LeadMatrixClose, do.NULL = FALSE, prefix = ""), 
           colnames(LeadMatrixClose, do.NULL = FALSE, prefix = "LeadC")) 
df <- cbind(df, LeadMatrixClose) 

这是创建并添加到DF既滞后和铅矩阵最终输出的样子:

Close LagC1 LagC2 LagC3 LeadC1 LeadC2 LeadC3 
1 1221 NA NA NA 1220 1220 1217 
2 1220 1221 NA NA 1220 1217 1216 
3 1220 1220 1221 NA 1217 1216 1218 
4 1217 1220 1220 1221 1216 1218 1216 
5 1216 1217 1220 1220 1218 1216 1216 
6 1218 1216 1217 1220 1216 1216 1217 
7 1216 1218 1216 1217 1216 1217 1220 
8 1216 1216 1218 1216 1217 1220 1219 
9 1217 1216 1216 1218 1220 1219 1218 
10 1220 1217 1216 1216 1219 1218 1220 
11 1219 1220 1217 1216 1218 1220 1216 
12 1218 1219 1220 1217 1220 1216 1217 
13 1220 1218 1219 1220 1216 1217 1218 
14 1216 1220 1218 1219 1217 1218 1218 
15 1217 1216 1220 1218 1218 1218 1207 
16 1218 1217 1216 1220 1218 1207 1206 
17 1218 1218 1217 1216 1207 1206 1205 
18 1207 1218 1218 1217 1206 1205  NA 
19 1206 1207 1218 1218 1205  NA  NA 
20 1205 1206 1207 1218  NA  NA  NA 
+0

谢谢大卫!这正是我所期待的!用一行代码解决了我的问题,而不是使用'for'循环。 – Krug

回答

2

data.table::shift函数n参数接受一个向量,也可以运行leadlag转换。所以这应该是相当直接和向量化

library(data.table) # v >= 1.9.6 
m <- 3  
setDT(df)[, paste0("LagC", 1:m) := shift(Close, 1:m)] 
df[, paste0("LeadC", 1:m) := shift(Close, 1:m, type = "lead")] 
df 

#  Close LagC1 LagC2 LagC3 LeadC1 LeadC2 LeadC3 
# 1: 1221 NA NA NA 1220 1220 1217 
# 2: 1220 1221 NA NA 1220 1217 1216 
# 3: 1220 1220 1221 NA 1217 1216 1218 
# 4: 1217 1220 1220 1221 1216 1218 1216 
# 5: 1216 1217 1220 1220 1218 1216 1216 
# 6: 1218 1216 1217 1220 1216 1216 1217 
# 7: 1216 1218 1216 1217 1216 1217 1220 
# 8: 1216 1216 1218 1216 1217 1220 1219 
# 9: 1217 1216 1216 1218 1220 1219 1218 
# 10: 1220 1217 1216 1216 1219 1218 1220 
# 11: 1219 1220 1217 1216 1218 1220 1216 
# 12: 1218 1219 1220 1217 1220 1216 1217 
# 13: 1220 1218 1219 1220 1216 1217 1218 
# 14: 1216 1220 1218 1219 1217 1218 1218 
# 15: 1217 1216 1220 1218 1218 1218 1207 
# 16: 1218 1217 1216 1220 1218 1207 1206 
# 17: 1218 1218 1217 1216 1207 1206 1205 
# 18: 1207 1218 1218 1217 1206 1205  NA 
# 19: 1206 1207 1218 1218 1205  NA  NA 
# 20: 1205 1206 1207 1218  NA  NA  NA 
1

它可能看起来不优雅,但应该工作。我们总是可以创造滞后和领先的功能,但有三个滞后和领导,这应该没问题。

df <- data.frame(Close = c(1221, 1220, 1220, 1217, 1216, 1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205)) 

df$lag1 <- c(rep(NA, 1), head(df$Close, -1)) 
df$lag2 <- c(rep(NA, 2), head(df$Close, -2)) 
df$lag3 <- c(rep(NA, 3), head(df$Close, -3)) 

df$lead1 <- c(tail(df$Close, -1), rep(NA, 1)) 
df$lead1 <- c(tail(df$Close, -2), rep(NA, 2)) 
df$lead1 <- c(tail(df$Close, -3), rep(NA, 3)) 

编辑:对于一般的情况下,

# Functions 
add.lag <- function(x, n.lag, col.id) { 
    for (i in 1:n.lag) { 
    x[paste0("lag", i)] <- c(rep(NA, i), head(x[[col.id]], -i)) 
    } 
    x 
} 

add.lead <- function(x, n.lead, col.id) { 
    for (i in 1:n.lead) { 
    x[paste0("lead", i)] <- c(tail(x[[col.id]], -i), rep(NA, i)) 
    } 
    x 
} 

# Apply functions 
df <- add.lag(df, 3, 'Close') 
df <- add.lead(df, 3, 'Close') 
+0

谢谢。我确实需要一般情况。只有简单的例子是前3行,实际上需要创建一个相当大的主值矩阵。 – Krug

1

我真的不明白的结果应该是什么样子,但这里是一个构建块使用dplyr

df <- data.frame(Close = c(1221, 1220, 1220, 1217, 1216, 1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205)) 

require(dplyr) 

dplyr::lag(df$Close, n=1) 
[1] NA 1221 1220 1220 1217 1216 1218 1216 1216 1217 1220 1219 1218 1220 1216 1217 1218 1218 1207 1206 

dplyr::lead(df$Close, n=1) 
[1] 1220 1220 1217 1216 1218 1216 1216 1217 1220 1219 1218 1220 1216 1217 1218 1218 1207 1206 1205 NA 

df_lags <- data.frame(sapply(1:3, function(nl) {dplyr::lag(df$Close, n=nl)})) 
df_leads <- data.frame(sapply(1:3, function(nl) {dplyr::lead(df$Close, n=nl)})) 
+0

优秀的解决方案。当想要创建单独的滞后/前导矩阵时(即不是源矩阵的一部分)的理想选择。将会使用这个。谢谢。 – Krug