Độ trễ trong một chuỗi thời gian được nhóm lại


10

Tôi có một vài chục ngàn quan sát trong một chuỗi thời gian nhưng được nhóm theo địa điểm. Ví dụ:

location date     observationA observationB
---------------------------------------
 A       1-2010   22           12
 A       2-2010   26           15
 A       3-2010   45           16
 A       4-2010   46           27
 B       1-2010   167          48
 B       2-2010   134          56
 B       3-2010   201          53
 B       4-2010   207          42

Tôi muốn nhìn thấy nếu tháng x 's observationAcó bất kỳ mối quan hệ tuyến tính với tháng x +1 observationB.

Tôi đã thực hiện một số nghiên cứu và tìm thấy một zoochức năng, nhưng dường như không có cách nào để hạn chế độ trễ theo nhóm. Vì vậy, nếu tôi sử dụng vườn thú và tụt observationBbởi 1 hàng, tôi muốn kết thúc với vị trí của một cuối cùng observationBnhư vị trí của B đầu tiên observationB. Tôi muốn có vị trí đầu tiên observationBcủa bất kỳ vị trí nào NAhoặc một số giá trị rõ ràng khác để cho biết "không chạm vào hàng này".

Tôi đoán những gì tôi nhận được là liệu có một cách tích hợp để làm điều này trong R không? Nếu không, tôi tưởng tượng tôi có thể hoàn thành việc này với cấu trúc vòng lặp tiêu chuẩn. Hay tôi thậm chí cần phải thao tác dữ liệu?

Câu trả lời:


23

Có một số cách bạn có thể nhận được một biến bị trễ trong một nhóm. Trước hết bạn nên sắp xếp dữ liệu, để trong mỗi nhóm thời gian được sắp xếp tương ứng.

Đầu tiên chúng ta hãy tạo một data.frame mẫu:

> set.seed(13)
> dt <- data.frame(location = rep(letters[1:2], each = 4), time = rep(1:4, 2), var = rnorm(8))
> dt
  location time        var
1        a    1  0.5543269
2        a    2 -0.2802719
3        a    3  1.7751634
4        a    4  0.1873201
5        b    1  1.1425261
6        b    2  0.4155261
7        b    3  1.2295066
8        b    4  0.2366797

Xác định hàm lag của chúng tôi:

 lg <- function(x)c(NA, x[1:(length(x)-1)])
  1. Sau đó, độ trễ của biến trong nhóm có thể được tính bằng cách sử dụng tapply:

     > unlist(tapply(dt$var, dt$location, lg))
        a1         a2         a3         a4         b1         b2         b3         b4 
        NA  0.5543269 -0.2802719  1.7751634         NA  1.1425261  0.4155261  1.2295066
  2. Sử dụng ddplytừ gói plyr :

    > ddply(dt, ~location, transform, lvar = lg(var))
      location time        var       lvar
    1        a    1 -0.1307015         NA
    2        a    2 -0.6365957 -0.1307015
    3        a    3 -0.6417577 -0.6365957
    4        a    4 -1.5191950 -0.6417577
    5        b    1 -1.6281638         NA
    6        b    2  0.8748671 -1.6281638
    7        b    3 -1.3343222  0.8748671
    8        b    4  1.5431753 -1.3343222  
  3. Phiên bản nhanh hơn sử dụng data.tabletừ gói data.table

     > ddt <- data.table(dt)
     > ddt[,lvar := lg(var), by = c("location")]
         location time        var       lvar
    [1,]        a    1 -0.1307015         NA
    [2,]        a    2 -0.6365957 -0.1307015
    [3,]        a    3 -0.6417577 -0.6365957
    [4,]        a    4 -1.5191950 -0.6417577
    [5,]        b    1 -1.6281638         NA
    [6,]        b    2  0.8748671 -1.6281638
    [7,]        b    3 -1.3343222  0.8748671
    [8,]        b    4  1.5431753 -1.3343222
  4. Sử dụng lagchức năng từ gói plm

     > pdt <- pdata.frame(dt)
     > lag(pdt$var)
       a-1        a-2        a-3        a-4        b-1        b-2        b-3        b-4 
        NA  0.5543269 -0.2802719  1.7751634         NA  1.1425261  0.4155261  1.2295066
  5. Sử dụng lagchức năng từ gói dplyr

    > dt %>% group_by(location) %>% mutate(lvar = lag(var))        
    Source: local data frame [8 x 4]
    Groups: location        
      location time        var       lvar
    1        a    1  0.5543269         NA
    2        a    2 -0.2802719  0.5543269
    3        a    3  1.7751634 -0.2802719
    4        a    4  0.1873201  1.7751634
    5        b    1  1.1425261         NA
    6        b    2  0.4155261  1.1425261
    7        b    3  1.2295066  0.4155261
    8        b    4  0.2366797  1.2295066

Hai cách tiếp cận cuối cùng yêu cầu chuyển đổi từ data.frameđối tượng khác, mặc dù sau đó bạn không cần phải lo lắng về việc sắp xếp. Sở thích cá nhân của tôi là cái cuối cùng, không có sẵn khi viết câu trả lời ban đầu.

Cập nhật: Đã thay đổi mã data.table để phản ánh sự phát triển của gói data.table, được chỉ ra bởi @Hibernating.

Cập nhật 2: Đã thêm ví dụ dplyr .


Giải thích tuyệt vời! Có một gói / chức năng có thể đối phó với chuỗi thời gian được nhóm không đều nhau (bảng) và bảng không cân bằng?
Helix123

Tất cả các ví dụ mã sẽ làm việc cho các bảng không cân bằng. Đối với chuỗi thời gian cách đều nhau, khái niệm độ trễ hơi phức tạp, vì nó có thể không tồn tại cho tất cả các nhóm.
mpiktas

Bạn có thể hỏi về độ trễ cho chuỗi thời gian không đều trong stackoverflow. Các loại câu hỏi này hiện không có chủ đề trong thống kê.SE.
mpiktas

2

@ mpiktas Chỉ cần đề cập ngắn gọn về hai câu hỏi nhỏ trong phiên bản 3 của câu trả lời của bạn. Thứ nhất, cụm từ "phiên bản nhanh hơn" rõ ràng đã bị lỗi. Thứ hai, từ ": =" đã bị bỏ sót trong mã. Sửa lỗi sau sửa lỗi trước: =)

library(data.table);ddt <- data.table(dt)
f0<-function() plyr::ddply(dt,~location,transform,lvar=lg(var))
f1<-function() ddt[,transform(.SD,lvar=lg(var)),by=c("location")]
f2<-function() ddt[,lvar:=lg(var),by=location]
r0<-f0();r1<-f1();r2<-f2();all.equal(r0,r1,r2,check.attributes = FALSE)
boxplot(microbenchmark::microbenchmark(f0(),f1(),f2(),times=1000L))

nhập mô tả hình ảnh ở đây


2

Thay vì thực hiện tất cả các tapplybước và các bước bổ sung, đây là cách nhanh hơn:

dt<-data.frame(location=rep(letters[1:2],each=4),time=rep(1:4,2),var=rnorm(8))
lg<-function(x)c(NA,x[1:(length(x)-1)])
dt$lg <- ave(dt$var, dt$location, FUN=lg)

2

Với dplyr

dt %>% group_by(location) %>% mutate(lvar=lag(var))


0

Với DataCombine:

library(DataCombine)
slide(df, Var="observationB", TimeVar="date", GroupVar="location", NewVar="lead.observationB", 
slideBy = 1, keepInvalid = FALSE, reminder = FALSE)

Dữ liệu cần phải được sắp xếp là tốt. Sử dụng slideBy=-1thay cho độ trễ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.