2012-02-24 18 views
6

Ví dụ, giả sử bạn có ~ 10 năm ngày 1 dữ liệu tối thiểu cho khối lượng cụ x như sau (ở định dạng xts) 9:30-04:30:Phương pháp nào tốt nhất để thu thập số liệu khối lượng trong ngày từ một khoảng thời gian giá cổ phiếu bằng cách sử dụng XTS/ZOO vv trong R?

Date.Time    Volume   
    2001-01-01 09:30:00  1200 
    2001-01-01 09:31:00  1110 
    2001-01-01 09:32:00  1303 

Tất cả các cách thức thông qua để:

2010-12-20 16:28:00  3200 
    2010-12-20 16:29:00  4210 
    2010-12-20 16:30:00  8303 

tôi muốn:

  • Lấy khối lượng trung bình tại mỗi phút cho toàn bộ loạt (tức là khối lượng trung bình trên tất cả 10 năm lúc 9:30, 9:31, 09:32 ... 16:28, 16:29, 16:30)

Làm thế nào tôi nên đi tốt nhất về:

  • Tập hợp các dữ liệu vào xô một phút
  • Lấy trung bình của những thùng đó
  • Tái tạo lại những nhóm "trung bình" đó trở lại chuỗi thời gian xts/sở thú duy nhất?

Tôi đã có một xô tốt xung quanh với aggregate, sapply, period.apply chức năng vv, nhưng chỉ dường như không thể "bin" các dữ liệu một cách chính xác.

Thật dễ dàng để giải quyết vấn đề này với vòng lặp, nhưng rất chậm. Tôi muốn tránh một giải pháp có lập trình và sử dụng chức năng tận dụng kiến ​​trúc C++ (tức là giải pháp dựa trên xts)

Có ai có thể đưa ra một số lời khuyên/giải pháp không?

Cảm ơn bạn rất nhiều trước.

Trả lời

5

Đầu tiên cho phép tạo ra một số dữ liệu thử nghiệm:

library(xts) # also pulls in zoo 
library(timeDate) 
library(chron) # includes times class 

# test data 
x <- xts(1:3, timeDate(c("2001-01-01 09:30:00", "2001-01-01 09:31:00", 
    "2001-01-02 09:30:00"))) 

1) aggregate.zoo. Bây giờ hãy thử chuyển đổi nó để times lớp và tổng hợp sử dụng này một liner:

aggregate(as.zoo(x), times(format(time(x), "%H:%M:%S")), mean) 

1a) aggregate.zoo (biến thể). hoặc sự thay đổi này mà chuyển đổi hàng loạt tổng hợp ngắn hơn để times để tránh phải làm điều đó trên loạt gốc còn:

ag <- aggregate(as.zoo(x), format(time(x), "%H:%M:%S"), mean) 
zoo(coredata(ag), times(time(ag))) 

2) tapply.Một thay thế sẽ là tapply đó là khả năng nhanh hơn:

ta <- tapply(coredata(x), format(time(x), "%H:%M:%S"), mean) 
zoo(unname(ta), times(names(ta))) 

EDIT: đơn giản (1) và gia tăng (1a) và (2)

+0

Tuyệt vời. Điều này là rất, rất tốt. –

+0

Cảm ơn bạn đã đăng giải pháp rất thanh lịch này. –

3

Đây là một giải pháp với ddply, nhưng bạn có thể có lẽ cũng sử dụng sqldf, tapply, aggregate, by vv

# Sample data 
minutes <- 10 * 60 
days <- 250 * 10 
d <- seq.POSIXt( 
    ISOdatetime(2011,01,01,09,00,00, "UTC"), 
    by="1 min", length=minutes 
) 
d <- outer(d, (1:days) * 24*3600, `+`) 
d <- sort(d) 
library(xts) 
d <- xts(round(100*rlnorm(length(d))), d) 

# Aggregate 
library(plyr) 
d <- data.frame( 
    minute=format(index(d), "%H:%M"), 
    value=coredata(d) 
) 
d <- ddply( 
    d, "minute", 
    summarize, 
    value=mean(value, na.rm=TRUE) 
) 

# Convert to zoo or xts 
zoo(x=d$value, order.by=d$minute) # The index does not have to be a date or time 
xts(x=d$value, order.by=as.POSIXct(sprintf("2012-01-01 %s:00",d$minute), "%Y-%m-%d %H:%M:%S")) 
+0

Cảm ơn cho việc này. Tôi đã nghĩ đến 'sqldf', nhưng nó có vẻ giống như một" gian lận "cho những gì tôi đang cố gắng đạt được. Bây giờ đến mã của bạn. Tính năng này hoạt động tốt với việc sử dụng 'ddply' (nghĩa là tôi đã tạo khung dữ liệu với phút và giá trị (được cấu trúc là chr và num tương ứng) .Tuy nhiên, nó chỉ trả về" NA "cho (trung bình) Giá trị cột Bất kỳ ý tưởng nào? –

+0

Xin lỗi - Tôi phải nói rằng mã mô hình của bạn hoạt động tốt trong suốt. 1: 976638, 1] 46 32 24 7 34 27 9 18 2 24 ... - attr (*, "dimnames") = Danh sách 2 .. $: NULL .. $: chr "Tập" /// và 'chỉ mục' của dữ liệu của tôi: Lớp chính thức 'timeDate' [gói" fCalendar "] với 3 giây rất nhiều .. @ Dữ liệu: POSIXct [1: 976638], định dạng: "2001-07-02 09:51:00" "2001-07-02 09:52:00" "2001-07-02 09:53: 00 "" 2001-07-02 09:54:00 "... .. @ định dạng: chr"% Y-% m-% d% H:% M:% S " –

+0

Lỗi được trả lại trong sự thích ứng của tôi là: Trong mean.default (giá trị, na.rm = TRUE): đối số không phải là số hoặc hợp lý: trả về NA –