Базовое отставание в R вектор / датафрейм - PullRequest
35 голосов
/ 24 августа 2010

Скорее всего, я покажу, что я новичок в R, но в SPSS работать с лагами очень просто.Очевидно, что это ошибка пользователя, но чего мне не хватает?

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

Результаты в:будет высоко ценится.

Ответы [ 11 ]

27 голосов
/ 24 августа 2010

Еще один способ справиться с этим - использовать пакет zoo, который имеет метод задержки, который дополнит результат 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))
26 голосов
/ 29 октября 2012

У меня была такая же проблема, но я не хотел использовать zoo или xts, поэтому я написал простую функцию lag для фреймов данных :

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
15 голосов
/ 24 августа 2010

lag не сдвигает данные, он только сдвигает «временную базу». x не имеет «временной базы», ​​поэтому cbind работает не так, как вы ожидали. Попробуйте cbind(as.ts(x),lag(x)) и обратите внимание, что "лаг" 1 сдвигает периоды вперед .

Я бы предложил использовать zoo / xts для временных рядов. Особенно полезны zoo виньетки.

7 голосов
/ 24 августа 2010

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
5 голосов
/ 02 декабря 2014

Используя только стандартные функции R, это можно сделать гораздо проще:

x <- sample(c(1:9), 10, replace = T)
y <- c(NA, head(x, -1))
ds <- cbind(x, y)
ds
3 голосов
/ 13 октября 2015

Самый простой способ для меня сейчас выглядит следующим образом:

require(dplyr)
df <- data.frame(x = sample(c(1:9), 10, replace = T))
df <- df %>% mutate(y = lag(x))
2 голосов
/ 23 октября 2013

Это должно учитывать векторы или матрицы, а также отрицательные лаги:

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
}
2 голосов
/ 18 марта 2013
tmp<-rnorm(10)
tmp2<-c(NA,tmp[1:length(tmp)-1])
tmp
tmp2
0 голосов
/ 20 декабря 2018

Два варианта: base R и 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
0 голосов
/ 27 октября 2016

простым способом сделать то же самое может быть копирование данных в новый фрейм данных и изменение номера индекса.Убедитесь, что исходная таблица последовательно проиндексирована без пробелов

например,

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

, если вы хотите, чтобы она находилась в том же фрейме данных, что и оригинал, используйте функцию cbind

...