如何滞后向量然后创建矩阵?

时间:2019-02-15 09:29:59

标签: r vector lag

我打算编写一个名为lagit(a,k)的函数来获得如下结果:

lagit(c(1,5,6,4,7),c(1,3))

然后它应该输出:

    L0 L1 L3
    1  NA NA
    5  1  NA
    6  5  NA
    4  6  1
    7  4  5

我现在面临两个问题:
1.滞后于每列作为向量k中的每个元素;
2.如何将向量绑定到矩阵(我使用了for loop

只要求我使用base中的功能。所以我不能从其他包中调用任何函数。

5 个答案:

答案 0 :(得分:2)

尝试一下:

lagit <- function(a,k) {
   tmp <- lapply(k,function(i) c(rep(NA,i),head(a,length(a)-i)))
   res <- cbind(a,do.call(cbind,tmp))
   colnames(res) <- paste0("L",c(0,k))
   res
}
lagit(a,k)
#[1,] 1 NA NA
#[2,] 5  1 NA
#[3,] 6  5 NA
#[4,] 4  6  1
#[5,] 7  4  5

位置:

a <- c(1,5,6,4,7)
k <- c(1,3)

答案 1 :(得分:1)

这是另一种方法

x <- c(1,5,6,4,7)

# Define a function that operates on a vector x
lagit <- function(x, k) {
    stopifnot(k >= 0 & k <= length(x))
    replace(rep(NA, length(x)), (k + 1):length(x), x[1:(length(x) - k)])
}

虽然不是绝对必要,但我添加了stopifnot语句以确保滞后为正且小于或等于向量的长度。

# Use sapply to apply lagit to different lags and store result as a matrix
sapply(c(0, 1, 3), function(k) lagit(x, k))
#     [,1] [,2] [,3]
#[1,]    1   NA   NA
#[2,]    5    1   NA
#[3,]    6    5   NA
#[4,]    4    6    1
#[5,]    7    4    5

答案 2 :(得分:0)

一个递归解决方案:

myLag <- function(x, n){
  if(n > 0) myLag(c(NA, x)[1:length(x)], n-1) else x
}

此功能的功能等效于dplyr::lag()data.table::shift()。让我们测试一下:

myLag(1:10, 3)
# [1] NA NA NA  1  2  3  4  5  6  7

在您的情况下:

a <- c(1,5,6,4,7)
b <- c(1,3)

> sapply(b, myLag, x = a)

[1,]   NA   NA
[2,]    1   NA
[3,]    5   NA
[4,]    6    1
[5,]    4    5

> cbind(a, sapply(b, myLag, x = a))

[1,] 1 NA NA
[2,] 5  1 NA
[3,] 6  5 NA
[4,] 4  6  1
[5,] 7  4  5

答案 3 :(得分:0)

base R解决方案

myLag <- function(x, n){
  if(n >= length(x))
    return(rep(NA,n))
  else if(n < length(x) & n > 0) 
    c(rep(NA,n), x[1:(length(x)-n)]) 
  else 
    x
}

lagit <- function(x,y){
  cbind(x, sapply(y, function(z) myLag(x,z)))
}

> lagit(c(1,5,6,4,7),c(1,3))
     x      
[1,] 1 NA NA
[2,] 5  1 NA
[3,] 6  5 NA
[4,] 4  6  1
[5,] 7  4  5

答案 4 :(得分:0)

另一个选择是在引擎盖下使用vapplylength<-

lagit <- function(a, k) {
  l <- length(a)
  k <- if (0 %in% k) k else c(0, k)
  vapply(k, function(x) `length<-`(c(rep(NA, times = x), a), l), numeric(l))
}
lagit(1:5, c(1, 3, 6))
#     [,1] [,2] [,3] [,4]
#[1,]    1   NA   NA   NA
#[2,]    2    1   NA   NA
#[3,]    3    2   NA   NA
#[4,]    4    3    1   NA
#[5,]    5    4    2   NA