2012-12-27 39 views
12

Tôi đang sử dụng phiên bản data.table mới và đặc biệt là chức năng AWESOME fread. Tệp của tôi chứa ngày được tải dưới dạng chuỗi (vì tôi không biết làm cách nào khác) trông giống như 01APR2008:09:00:00.truyền chuỗi trực tiếp đến IDateTime

Tôi cần phải sắp xếp dữ liệu. Có thể vào các khoảng thời gian đó và sau đó sắp xếp để có hiệu quả để đúc sau đó ở định dạng IDateTime (hoặc bất kỳ điều gì tôi chưa biết).

> strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S") 
[1] "2008-04-01 09:00:00" 

> IDateTime(strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S")) 
     idate itime 
1: 2008-04-01 09:00:00 

> IDateTime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S") 
Error in charToDate(x) : 
character string is not in a standard unambiguous format 

Có vẻ như tôi không thể làm DT[ , newType := IDateTime(strptime(oldType, "%d%b%Y:%H:%M:%S"))].

Câu hỏi của tôi là sau đó:

  1. Có cách nào để cast trực tiếp đến IDateTime từ fread, như vậy mà tôi có thể sắp xếp sau đó một cách hiệu quả?
  2. Nếu không, cách hiệu quả nhất để đi khi biết rằng tôi muốn để có thể sắp xếp DT theo cột datetime này
+0

bạn có thể cho biết cách họ xem tệp dữ liệu của bạn không? – agstudy

+0

Xin chào, tệp là tệp csv có 'sep ="; "' và định dạng ngày trông giống như "01APR2008: 09: 00: 00" 'là' format = "% d% b% Y:% H: % M:% S "'. Những gì tôi đã làm là 'DT [, ngày: = IDate (oldType,"% d% b% Y ")]; DT [, thời gian: = ITime (oldType,"% d% b% Y:% H:% M :% S ")]' và cuối cùng 'setkeyv (DT, c (" ngày "," thời gian "))' – statquant

+0

ngày là cột đầu tiên của dữ liệu của bạn? – agstudy

Trả lời

11

Thật không may là những gì (đối với hiệu quả) strptime tạo ra một loại POSIXlt, không được hỗ trợ bởi data.table và sẽ luôn có kích thước (40 byte mỗi ngày!) Và cấu trúc. Mặc dù strftime tạo ra POSIXct tốt hơn nhiều, nó vẫn thực hiện qua POSIXlt. Xem thêm thông tin ở đây:

http://stackoverflow.com/a/12788992/403310 

Nhìn về căn cứ chức năng như as.Date, nó sử dụng strptime quá, tạo ra một số nguyên bù đắp từ thời đại (kỳ quặc) được lưu trữ như gấp đôi. Lớp IDate (và bạn bè) trong data.table nhằm mục đích để đạt được số nguyên epoch bù đắp được lưu trữ như, um, số nguyên. Thích hợp để phân loại nhanh theo base::sort.list(method = "radix") (đây thực sự là một loại đếm). IDate không thực sự nhằm mục đích chuyển đổi nhanh (thường là một lần).

Vì vậy, để chuyển đổi ngày/giờ chuỗi, đúng hay sai, tôi có xu hướng cuộn chức năng trợ giúp của riêng mình.

Nếu ngày chuỗi là "2012-12-24" Tôi muốn hướng đến: as.integer(gsub("-", "", col)) và tiếp tục với YYYYMMDD ngày nguyên. Tương tự, thời gian có thể là HHMMDD dưới dạng số nguyên. Hai cột: datetime riêng biệt có thể hữu ích nếu bạn thường muốn roll = TRUE trong vòng một ngày, nhưng không phải cho ngày trước đó. Nhóm theo tháng rất đơn giản và nhanh chóng: by = date %/% 100L. Thêm và trừ ngày là phiền hà, nhưng nó là anyway bởi vì hiếm khi nào bạn muốn thêm ngày dương lịch, thay vì ngày thường hoặc ngày làm việc. Vì vậy, đó là một tra cứu cho vector ngày làm việc của bạn anyway.

Trong trường hợp của bạn, tháng ký tự sẽ cần chuyển đổi thành 1:12. Không có dấu tách trong ngày "01APR2008" của bạn, do đó, substring sẽ là một chiều theo sau là match hoặc fmatch trên tên tháng. Bạn có kiểm soát được định dạng tệp không? Nếu vậy, số sẽ tốt hơn ở định dạng rõ ràng, tự động sắp xếp theo thứ tự như %Y-%m-%d hoặc %Y%m%d.

Tôi chưa biết cách thực hiện tốt nhất trong fread, vì vậy ngày/giờ được để lại dưới dạng ký tự hiện tại vì tôi chưa biết cách phát hiện định dạng ngày hoặc loại đầu ra nào. Nó không cần xuất hoặc là số nguyên hoặc ngày kép mặc dù, chứ không phải là ký tự không hiệu quả.Tôi nghi ngờ rằng việc sử dụng YYYYMMDD số nguyên của tôi được xem là độc đáo, vì vậy tôi hơi lưỡng lự để làm điều đó mặc định. Họ có vị trí của họ, và có những ưu và nhược điểm của thời đại dựa trên quá. Ngày không luôn là thời đại trên tất cả những gì tôi đề xuất.

Bạn nghĩ sao? Btw, cảm ơn sự khuyến khích trên fread; đã được tốt đẹp để xem.

+0

Hey Matthew cảm ơn bạn đã trả lời, một khả năng là tôi đoán để cho phép một đối số colClasses như trong read.csv. Sau khi tất cả các bạn có thể chỉ định định dạng của riêng bạn như trong (tha thứ các exemple tôi lấy từ bài khác) 'R) setAs (" ký tự "," myDate ", chức năng (từ) as.Date (from, format ="% d/% m /% y "))' 'R) system.time (dữ liệu <- read.csv (tệp = filePath, sep = ";", stringsAsFactors = TRUE, colClasses = c ("yếu tố", "yếu tố" , "số", "myDate"), nrows = 10)); ' – statquant

+0

Ngoài ra, tôi nghĩ bạn sẽ chạm vào nhiều người hơn nếu bạn có thể thêm thời gian phân giải micro giây trong gói. Tất cả các HFTraders/quants đang chơi với công cụ này ... (có lẽ họ không nên sử dụng R cho điều này nhưng chúng ta không đi đến đó) – statquant

+0

Đồng ý, 'colClasses' đã có trong danh sách để thêm (danh sách TO DO ở trên cùng của fread .c), nhưng như một vector được đặt tên cho phép ghi đè các cột cụ thể thay vì cần chỉ định tất cả các cột đó. Đó là một câu hỏi về mặc định thực sự. Tôi giả sử 'POSIXct', sau đó. Điều đó hỗ trợ micro giây đã được vì vậy tôi không thấy rằng như bất cứ điều gì đặc biệt 'data.table' cần phải hỗ trợ thực sự, iiuc (khác hơn là fread có thể tải chúng lên trực tiếp và nhanh chóng). Lý do chính tôi muốn làm fread là cho các tập tin phân tách kép (sep2), mặc dù, chẳng hạn như trong bộ gen. –

1

Tôi không biết tệp của bạn được cấu trúc như thế nào, nhưng từ nhận xét của bạn, bạn muốn sử dụng trường ngày làm khóa. Tại sao không đọc nó như một chuỗi thời gian và định dạng nó khi đọc?

Ở đây tôi sử dụng sở thú để làm điều đó. (Ở đây tôi giả sử rằng cột ngày là một trong những đầu tiên, nếu không thấy index.colum luận)

ff <- function(x) as.POSIXct(strptime(x,"%d%b%Y:%H:%M:%S")) 

h <- read.zoo(text = "03avril2008:09:00:00 125 
         02avril2008:09:30:00 126 
         05avril2008:09:10:00 127 
         04avril2008:09:20:00 128 
         01avril2008:09:00:00 128" 
         ,FUN=ff) 

Bạn được ngày của bạn được sắp xếp trong định dạng phù hợp và sắp xếp.

Việc chuyển đổi là tự nhiên từ POSIXct để IDateTime

IDateTime(index(h)) 
     idate itime 
1: 2008-04-01 09:00:00 
2: 2008-04-02 09:30:00 
3: 2008-04-03 09:00:00 
4: 2008-04-04 09:20:00 
5: 2008-04-05 09:10:00 

Đây chắc chắn rằng bạn vẫn làm 2 chuyển đổi, Nhưng bạn làm điều đó khi đọc dữ liệu, và thứ hai bạn làm điều đó mà không cần đối phó với bất kỳ vấn đề định dạng.

Các vấn đề liên quan