2012-01-18 33 views
9

Tôi có một bộ dữ liệu tương tự như nàylag chung dữ liệu bảng của chuỗi thời gian

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 

Tôi muốn tạo ra một độ trễ của Value, tôn trọng User.

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 

tôi đã thực hiện nó rất không hiệu quả trong một vòng lặp

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 
     } 

Nhưng điều này là rất chậm. Tôi đã xem xét sử dụng bytapply, nhưng không tìm ra cách làm cho chúng hoạt động.

Tôi không nghĩ rằng XTS hoặc TS sẽ hoạt động vì yếu tố Người dùng.

Mọi đề xuất?

+0

Tôi nghĩ gói 'plm' có triển khai cho loại dữ liệu này. – Seb

Trả lời

8

Bạn có thể sử dụng ddply: cắt một khung dữ liệu thành từng phần và biến đổi từng phầ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

Hoạt động tốt. Cảm ơn Vincent. –

+0

Theo http://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-columns-in-r phân loại có thể được thực hiện với 'sắp xếp()' – pidosaurus

0

Tương tự, bạn có thể sử dụng 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)]))) 

Ý tưởng là giống hệt nhau: lấy giá trị, chia nó bằng cách sử dụng, và sau đó chạy một chức năng trên mỗi tập hợp con. Unlist đưa nó trở lại định dạng vector.

0

Được cung cấp bảng do Người dùng và Ngày đặt hàng, điều này có thể được thực hiện với zoo. Bí quyết không phải là để chỉ định một chỉ mục tại thời điểm này.

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 
0

Nếu bạn không có những khoảng trống trong biến thời gian, làm

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

Nếu bạn có những khoảng trống trong biến thời gian, thấy câu trả lời này https://stackoverflow.com/a/26108191/3662288

1

Đối với một bảng điều khiển mà không cần thiếu obs Đây là một giải pháp trực quan:

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ực dễ dàng nhất, đặc biệt là xem xét phân tích thêm, là chuyển đổi khung dữ liệu của bạn thành pdata.frame lớp học từ gói plm.

Sau khi chuyển đổi từ các toán tử diff()lag() có thể được sử dụng để tạo độ trễ và sự khác biệt của bảng điều khiển.

df<-pdata.frame(df,index=c("id","date") 
df<-transofrm(df, l_value=lag(value,1)) 
Các vấn đề liên quan