2012-05-11 28 views
7

Tôi có chuỗi thời gian bất thường của sự kiện (bài đăng) sử dụng xts và tôi muốn tính số sự kiện xảy ra trên cửa sổ hàng tuần (hoặc hai tuần một lần hoặc 3 ngày, v.v.). Các dữ liệu trông như thế này:Cửa sổ cuốn theo chuỗi thời gian bất thường

    postid 
2010-08-04 22:28:07 867 
2010-08-04 23:31:12 891 
2010-08-04 23:58:05 901 
2010-08-05 08:35:50 991 
2010-08-05 13:28:02 1085 
2010-08-05 14:14:47 1114 
2010-08-05 14:21:46 1117 
2010-08-05 15:46:24 1151 
2010-08-05 16:25:29 1174 
2010-08-05 23:19:29 1268 
2010-08-06 12:15:42 1384 
2010-08-06 15:22:06 1403 
2010-08-07 10:25:49 1550 
2010-08-07 18:58:16 1596 
2010-08-07 21:15:44 1608 

mà nên sản xuất cái gì đó như

    nposts 
2010-08-05 00:00:00  10 
2010-08-06 00:00:00  9 
2010-08-07 00:00:00  5 

cho một cửa sổ 2 ngày. Tôi đã xem xét rollapply, apply.rolling từ PerformanceAnalytics, v.v ... và tất cả đều giả định dữ liệu chuỗi thời gian thường xuyên. Tôi đã cố gắng thay đổi tất cả các lần để chỉ ngày bài viết xảy ra và sử dụng một cái gì đó như ddply để nhóm trên mỗi ngày, mà được tôi gần gũi. Tuy nhiên, người dùng có thể không đăng bài mỗi ngày, do đó, chuỗi thời gian sẽ vẫn không thường xuyên. Tôi có thể điền vào những khoảng trống với 0, nhưng điều đó có thể làm tăng dữ liệu của tôi rất nhiều và nó đã khá lớn.

Tôi nên làm gì?

+2

Giải pháp cho điều này hiện không tồn tại trong gói XTS, nhưng yêu cầu này đi lên đủ mà tôi đã bắt đầu suy nghĩ về bao gồm một giải pháp. –

+0

Bạn có cập nhật @JoshuaUlrich không? Hoặc một cái gì đó để có hiệu lực của câu trả lời dưới đây sẽ điền vào những ngày mất tích với dữ liệu zero hoặc NA để chúng ta có thể sử dụng 'rollapply'? Tôi đoán tôi có thể sử dụng 'hợp nhất' ... – flodel

+0

@ flodel: câu hỏi này không đòi hỏi những gì tôi nghĩ nó đã làm (xem câu trả lời của tôi). Tôi nghĩ rằng họ muốn nhìn lại 'n' ngày ở mọi quan sát trong chuỗi ban đầu của họ, đó là một vấn đề khó giải quyết hơn nhiều. –

Trả lời

4

Điều này dường như làm việc:

# n = number of days 
n <- 30 
# w = window width. In this example, w = 7 days 
w <- 7 

# I will simulate some data to illustrate the procedure 
data <- rep(1:n, rpois(n, 2)) 

# Tabulate the number of occurences per day: 
# (use factor() to be sure to have the days with zero observations included) 
date.table <- table(factor(data, levels=1:n)) 

mat <- diag(n) 
for (i in 2:w){ 
    dim <- n+i-1 
    mat <- mat + diag(dim)[-((n+1):dim),-(1:(i-1))] 
    } 

# And the answer is.... 
roll.mean.7days <- date.table %*% mat 

Có vẻ là không quá chậm (mặc dù ma trận mat sẽ nhận được kích thước n * n). Tôi đã cố gắng để thay thế n = 30 với n = 3000 (mà tạo ra một ma trận của 9 triệu yếu tố = 72 MB) và nó vẫn còn hợp lý nhanh trên máy tính của tôi. Đối với các tập dữ liệu rất lớn, hãy thử trên tập hợp con đầu tiên .... Sẽ nhanh hơn khi sử dụng một số chức năng trong gói Ma trận (bandSparse) để tạo ma trận mat.

+0

Đây là một cách hay để áp dụng cửa sổ cuộn cho một cái gì đó, nhưng nếu bạn không đưa ra ví dụ cho thấy cách áp dụng điều này cho một thời gian thực tế (thể hiện như đối tượng ngày giờ POSIXct như trong câu hỏi gốc), trả lời câu hỏi. – plannapus

+0

Với một vectơ của các đối tượng POSIXct không đều nhau, dữ liệu <- mẫu (seq (as.POSIXct ("2012/01/01"), as.POSIXct ("2012/01/31"), theo = "giờ") , 30) ', bạn có thể thay thế dòng' date.table' của bạn bằng cách: 'date.table <- table (cut (data," days "))' và sau đó tiến hành như bạn đã làm, và nó sẽ làm các trick. – plannapus

+0

plannapus, cảm ơn bạn đã bổ sung về các đối tượng POSIXct. –

3

Dưới đây là một giải pháp sử dụng XTS:

x <- structure(c(867L, 891L, 901L, 991L, 1085L, 1114L, 1117L, 1151L, 
    1174L, 1268L, 1384L, 1403L, 1550L, 1596L, 1608L), .Dim = c(15L, 1L), 
    index = structure(c(1280960887, 1280964672, 1280966285, 
    1280997350, 1281014882, 1281017687, 1281018106, 1281023184, 1281025529, 
    1281050369, 1281096942, 1281108126, 1281176749, 1281207496, 1281215744), 
    tzone = "", tclass = c("POSIXct", "POSIXt")), class = c("xts", "zoo"), 
    .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"), 
    .indexTZ = "", tzone = "") 
# first count the number of observations each day 
xd <- apply.daily(x, length) 
# now sum the counts over a 2-day rolling window 
x2d <- rollapply(xd, 2, sum) 
# align times at the end of the period (if you want) 
y <- align.time(x2d, n=60*60*24) # n is in seconds 
Các vấn đề liên quan