2010-08-24 4 views
27

J'exposerai très probablement que je suis nouveau dans R, mais dans SPSS, les décalages de fonctionnement sont très faciles. Evidemment c'est une erreur de l'utilisateur, mais qu'est-ce qui me manque?Retard de base dans le vecteur R/dataframe

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

Résultats dans:

 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 

Je pensais que je voyais:

 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 

Toute orientation sera très appréciée.

Répondre

23

Une autre façon de traiter ce problème est en utilisant le package zoo, qui a une méthode de décalage qui sera le résultat est complété 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 

Le résultat est un objet à plusieurs variables de zoo (qui est une matrice renforcée), mais facilement converti en un data.frame via

> data.frame(cbind(x, y)) 
+2

Notez également que si z est une série zoo alors lag (z, 0: -1) est une série zoo à deux colonnes avec la série originale et un série retardée. En outre, coredata (z) renverra juste la partie de données d'une série de zoo et as.data.frame (z) retournera une trame de données avec la partie de données de z comme contenu de colonne. –

13

lag ne décale pas les données, il ne fait que déplacer la "base de temps". x n'a pas de "base de temps", donc cbind ne fonctionne pas comme prévu. Essayez cbind(as.ts(x),lag(x)) et notez qu'un "décalage" de 1 décale les périodes avant.

Je suggère d'utiliser zoo/xts pour les séries temporelles. Les vignettes zoo sont particulièrement utiles.

+0

Ni 'zoo' ni' xts' semble être disponible, où dois-je les obtenir? – zwol

+2

'install.packages (" xts ") # cela va aussi installer le zoo –

6

lag() fonctionne avec des séries chronologiques, alors que vous essayez d'utiliser des matrices nues. This old question suggère d'utiliser à la place embed, comme ceci:

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

par exemple

> 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 
0

Il suffit de se débarrasser du lag.Changez votre ligne pour y à:

y <- c(NA, x[-1]) 
+7

ce n'est pas correct! Probablement que vous vouliez dire 'y <- c (NA, tête (x, -1))' – TMS

21

J'ai eu le même problème, mais je ne voulais pas utiliser zoo ou XTS, donc je l'ai écrit simple lag function for data frames:

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))); 
    } 
} 

Cela peut lag avant ou en arrière:

x<-1:3; 
(cbind(x, lagpad(x, 1), lagpad(x,-1))) 
    x  
[1,] 1 NA 2 
[2,] 2 1 3 
[3,] 3 2 NA 
+0

Disons que je voulais faire cette fonction sur un vecteur mais la préformer récursivement pour plusieurs décalages 'lagpad (x, -1: - 216) 'et sortir cette information dans une seule image (par exemple lagpad (x, -1) devient la variable # 1 de la df, lagpad (x, -2) devient la variable # 2 de la df, lagpad (x, -3) devient la variable n ° 3 de la df ... et ainsi de suite devrais-je cbind 216 colonnes ou existe-t-il un moyen plus court d'adapter votre code à ce scénario? – Danielle

2
tmp<-rnorm(10) 
tmp2<-c(NA,tmp[1:length(tmp)-1]) 
tmp 
tmp2 
2

Cela devrait accueillir des vecteurs ou des matrices, ainsi que les LAG négatives:

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 
} 
1

En utilisant uniquement des fonctions standard R ceci peut être réalisé d'une manière beaucoup plus simple:

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

La meilleure façon de me semble maintenant être les suivantes:

require(dplyr) 
df <- data.frame(x = sample(c(1:9), 10, replace = T)) 
df <- df %>% mutate(y = lag(x)) 
0

simple façon de faire de même peut être la copie des données à une nouvelle trame de données et en changeant le numéro d'index. Assurez-vous que la table d'origine est indexée séquentiellement sans espaces

par exemple.

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

si vous le voulez dans le même cadre de données que l'utilisation originale d'une fonction cbind