2012-01-18 24 views
9

私はUserを尊重し、Valueの遅れを作成したいこの一般的な遅れが

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 

に似たデータセットを持っています。

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 

私はループ

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 
     } 

で非常に非効率的にそれをやった。しかし、これは非常に遅いです。私はbytapplyを使ってみましたが、それらを動作させる方法は分かりませんでした。

User要素のためにXTSまたはTSが動作しないと思います。

提案がありますか?

+0

私は 'plm'パッケージにこのタイプのデータの実装があると思います。 – Seb

答えて

8

ddplyを使用すると、data.frameを分割して各部分を変換します。 、値をとり、ユーザがそれを分割し、各サブセットの機能を実行します。

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

よく機能します。ヴィンセントに感謝します。 –

+0

次のhttp://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-columns-in-rソートは 'arrange()'で行うことができます。 – pidosaurus

0

同様に、あなたのアイデアがまったく同じである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)]))) 

を使用することができます。 unlistはそれをベクトル形式に戻します。

0

表がユーザーと日付で注文されている場合は、これはzooで行うことができます。この時点でインデックスを指定するのは難しいことです。

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

を参照してください

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

を行います欠落しているのは直観的な解決策です。

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

インクは、特に、さらなる分析を行うことを考慮すると、パッケージからpdata.frameクラスにデータフレームを変換することが最も簡単な方法です。

diff()lag()の変換後、パネルのラグと相違点を作成することができます。

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