2012-01-18 29 views
9

ben User saygı Value bir gecikme oluşturmak istiyorum bugenel lag

User Date  Value 
A  2012-01-01 4 
A  2012-01-02 5 
A  2012-01-03 6 
A  2012-01-04 7 
B  2012-01-01 2 
B  2012-01-02 3 
B  2012-01-03 4 
B  2012-01-04 5 

benzeyen bir veri kümesi var.

User Date  Value Value.lag 
A  2012-01-01 4  NA 
A  2012-01-02 5  4 
A  2012-01-03 6  5 
A  2012-01-04 7  6 
B  2012-01-01 2  NA 
B  2012-01-02 3  2 
B  2012-01-03 4  3 
B  2012-01-04 5  4 

Ben bir döngü

df$value.lag1<-NA 
levs<-levels(as.factor(df$User)) 
levs 
    for (i in 1:length(levs)) { 
    temper<- subset(df,User==as.numeric(levs[i])) 
    temper<- rbind(NA,temper[-nrow(temper),]) 
df$value.lag1[df$User==as.numeric(as.character(levs[i]))]<- temper 
     } 

çok verimsiz yaptık Ama bu çok yavaş. Ben by ve tapply kullanarak baktım, ama onları nasıl çalıştıracağını anladım.

XTS veya TS'nin Kullanıcı öğesi nedeniyle çalışacağını sanmıyorum.

Herhangi bir öneriniz var mı?

+0

"plm" paketinin bu tür veriler için bir uygulaması olduğunu düşünüyorum. – Seb

cevap

8

ddply'u kullanabilirsiniz: bir data.frame'i parçalar halinde keser ve her parçayı dönüştürür. Değeri almak kullanıcı tarafından bölmek ve ardından her alt kümesine bir fonksiyon çalıştırın:

d <- data.frame( 
    User = rep(LETTERS[1:3], each=10), 
    Date = seq.Date(Sys.Date(), length=30, by="day"), 
    Value = rep(1:10, 3) 
) 
library(plyr) 
d <- ddply( 
    d, .(User), transform, 
    # This assumes that the data is sorted 
    Value = c(NA, Value[-length(Value)]) 
) 
+0

İyi çalışıyor. Teşekkürler Vincent. –

+0

http://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-columns-in-r aşağıdaki sıralama ile düzenleyebilirsiniz. – pidosaurus

0

Benzer şekilde, fikri tamamen aynıdır tapply

# Create Data 
user = c(rep('A',4),rep('B',4)) 
date = rep(seq(as.Date('2012-01-01'),as.Date('2012-01-04'),1),2) 
value = c(4:7,2:5) 
df = data.frame(user,date,value) 
# Get lagged values 
df$value.lag = unlist(tapply(df$value, df$user, function(x) c(NA,x[-length(df$value)]))) 

kullanabilirsiniz. Liste, tekrar vektör formatına geri getirir.

0

Tablonun Kullanıcı ve Tarih siparişi verildiğinde, bu zoo ile yapılabilir. Hile bu noktada bir dizin belirtmek değildir.

library(zoo) 
df <-read.table(text="User Date Value 
A 2012-01-01 4 
A 2012-01-02 5 
A 2012-01-03 6 
A 2012-01-04 7 
B 2012-01-01 2 
B 2012-01-02 3 
B 2012-01-03 4 
B 2012-01-04 5", header=TRUE, as.is=TRUE,sep = " ") 

out <-zoo(df) 

Value.lag <-lag(out,-1)[out$User==lag(out$User)] 
res <-merge.zoo(out,Value.lag) 
res <-res[,-(4:5)] # to remove extra columns 

    User.out Date.out Value.out Value.Value.lag 
1 A  2012-01-01 4   <NA>   
2 A  2012-01-02 5   4    
3 A  2012-01-03 6   5    
4 A  2012-01-04 7   6    
5 B  2012-01-01 2   <NA>   
6 B  2012-01-02 3   2    
7 B  2012-01-03 4   3    
8 B  2012-01-04 5   4 
1

bkz

df %>% group_by(User) %>% mutate(value_lag = lag(value, order_by =Date) 

do Bu eksik bir sezgisel çözümdür:

df <- data.frame(id = c(1, 1, 1, 1, 1, 2, 2), 
       date = c(1992, 1993, 1991, 1990, 1994, 1992, 1991), 
       value = c(4.1, 4.5, 3.3, 5.3, 3.0, 3.2, 5.2)) 

df<-df[with(df, order(id,date)), ] # sort by id and then by date 
df$l_value=c(NA,df$value[-length(df$value)]) # create a new var with data displaced by 1 unit 
df$l_value[df$id != c(NA, df$id[-length(df$id)])] =NA # NA data with different current and lagged id. 
df 

id date value l_value 
4 1 1990 5.3  NA 
3 1 1991 3.3  5.3 
1 1 1992 4.1  3.3 
2 1 1993 4.5  4.1 
5 1 1994 3.0  4.5 
7 2 1991 5.2  NA 
6 2 1992 3.2  5.2 
0

I th Mürekkep, özellikle daha fazla analiz yaparken, en kolay yolu, plm paketinden veri çerçevenizi pdata.frame sınıfına dönüştürmektir.Operatörler, panel gecikmeleri ve farkları oluşturmak için diff() ve lag() arasındaki dönüşümden sonra kullanılabilir.

df<-pdata.frame(df,index=c("id","date") 
df<-transofrm(df, l_value=lag(value,1)) 
İlgili konular