40

很可能会暴露我是 R 新手,但在 SPSS 中,运行滞后非常容易。显然这是用户错误,但我错过了什么?

x <- sample(c(1:9), 10, replace = T)
y <- lag(x, 1)
ds <- cbind(x, y)
ds

结果是:

      x y
 [1,] 4 4
 [2,] 6 6
 [3,] 3 3
 [4,] 4 4
 [5,] 3 3
 [6,] 5 5
 [7,] 8 8
 [8,] 9 9
 [9,] 3 3
[10,] 7 7

我想我会看到:

     x y
 [1,] 4 
 [2,] 6 4
 [3,] 3 6
 [4,] 4 3
 [5,] 3 4
 [6,] 5 3
 [7,] 8 5
 [8,] 9 8
 [9,] 3 9
[10,] 7 3

任何指导将不胜感激。

4

13 回答 13

35

我有同样的问题,但我不想使用 zoo 或 xts,所以我为数据帧编写了一个简单的滞后函数

lagpad <- function(x, k) {
  if (k>0) {
    return (c(rep(NA, k), x)[1 : length(x)] );
  }
  else {
    return (c(x[(-k+1) : length(x)], rep(NA, -k)));
  }
}

这可以向前或向后滞后:

x<-1:3;
(cbind(x, lagpad(x, 1), lagpad(x,-1)))
     x      
[1,] 1 NA  2
[2,] 2  1  3
[3,] 3  2 NA
于 2012-10-29T19:58:44.477 回答
29

解决这个问题的另一种方法是使用 zoo 包,它有一个 lag 方法,可以用 NA 填充结果:

require(zoo)
> set.seed(123)
> x <- zoo(sample(c(1:9), 10, replace = T))
> y <- lag(x, -1, na.pad = TRUE)
> cbind(x, y)
   x  y
1  3 NA
2  8  3
3  4  8
4  8  4
5  9  8
6  1  9
7  5  1
8  9  5
9  5  9
10 5  5

结果是一个多元动物园对象(这是一个增强矩阵),但很容易通过以下方式转换为 data.frame

> data.frame(cbind(x, y))
于 2010-08-24T17:28:29.317 回答
15

lag不会改变数据,它只会改变“时基”。 x没有“时间基准”,因此cbind无法按您的预期工作。尝试cbind(as.ts(x),lag(x))并注意 1 的“滞后”会使周期向前移动。

我建议将zoo/xts用于时间序列。小zoo插曲特别有用。

于 2010-08-24T17:15:17.083 回答
8

仅使用标准 R 函数,这可以通过更简单的方式实现:

x <- sample(c(1:9), 10, replace = T)
y <- c(NA, head(x, -1))
ds <- cbind(x, y)
ds
于 2014-12-02T00:11:53.320 回答
7

lag()适用于时间序列,而您正在尝试使用裸矩阵。 这个老问题建议embed改用,如下所示:

lagmatrix <- function(x,max.lag) embed(c(rep(NA,max.lag), x), max.lag+1)

例如

> x
[1] 8 2 3 9 8 5 6 8 5 8
> lagmatrix(x, 1)
      [,1] [,2]
 [1,]    8   NA
 [2,]    2    8
 [3,]    3    2
 [4,]    9    3
 [5,]    8    9
 [6,]    5    8
 [7,]    6    5
 [8,]    8    6
 [9,]    5    8
[10,]    8    5
于 2010-08-24T17:18:23.320 回答
6

现在对我来说最简单的方法似乎如下:

require(dplyr)
df <- data.frame(x = sample(c(1:9), 10, replace = T))
df <- df %>% mutate(y = lag(x))
于 2015-10-13T11:56:54.630 回答
2
tmp<-rnorm(10)
tmp2<-c(NA,tmp[1:length(tmp)-1])
tmp
tmp2
于 2013-03-18T18:34:23.093 回答
2

这应该适应向量或矩阵以及负滞后:

lagpad <- function(x, k=1) {
  i<-is.vector(x)
  if(is.vector(x)) x<-matrix(x) else x<-matrix(x,nrow(x))
  if(k>0) {
      x <- rbind(matrix(rep(NA, k*ncol(x)),ncol=ncol(x)), matrix(x[1:(nrow(x)-k),], ncol=ncol(x)))
  }
  else {
      x <- rbind(matrix(x[(-k+1):(nrow(x)),], ncol=ncol(x)),matrix(rep(NA, -k*ncol(x)),ncol=ncol(x)))
  }
  if(i) x[1:length(x)] else x
}
于 2013-10-23T19:37:15.580 回答
2

使用data.table

> x <- sample(c(1:9), 10, replace = T)
> y <- data.table::shift(x)
> ds <- cbind(x, y)
> ds
      x  y
 [1,] 5 NA
 [2,] 4  5
 [3,] 3  4
 [4,] 3  3
 [5,] 4  3
 [6,] 8  4
 [7,] 1  8
 [8,] 7  1
 [9,] 9  7
[10,] 7  9
于 2020-01-10T10:37:39.650 回答
0

一种简单的方法可能是将数据复制到新的数据框并更改索引号。确保原始表按顺序索引,没有间隙

例如

tempData <- originalData
rownames(tempData) <- 2:(nrow(tempData)+1)

如果您希望它与原始数据框位于相同的数据框中,请使用 cbind 函数

于 2016-10-27T13:26:25.263 回答
0

两个选项, inbase R和 with data.table

baseShiftBy1 <- function(x) c(NA, x[-length(x)])
baseShiftBy1(x)
[1] NA  3  8  4  8  9  1  5  9  5

data.table::shift(x)
[1] NA  3  8  4  8  9  1  5  9  5   

数据:

set.seed(123)
(x <- sample(c(1:9), 10, replace = T))
[1] 3 8 4 8 9 1 5 9 5 5
于 2018-12-20T15:34:27.437 回答
0

我采用了与Andrew 类似的解决方案(专用函数而不是xtsor zoo),但使用了更简洁的公式,我发现它更容易推理:

lagpad <- function(x, k) {
  if (k == 0) { return(x) }
  k.pos <- max(0, k)
  k.neg <- max(0, -k)
  c(rep(NA, k.pos), head(x, -k.pos),  # empty if k<0, else lagging x
    tail(x, -k.neg), rep(NA, k.neg))  # empty if k>0, else leading x
}
于 2020-08-20T21:18:26.983 回答
-1

只是摆脱滞后。将 y 行更改为:

y <- c(NA, x[-1])
于 2010-08-24T20:20:07.663 回答