创建主要变量矩阵

时间:2016-05-11 12:32:21

标签: r matrix dataframe

我有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

3 个答案:

答案 0 :(得分: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 :(得分: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')

答案 2 :(得分: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)}))