2013-02-18 33 views
12

Tôi có dữ liệu ngày trong biểu mẫu yyyy-ww trong đó ww là số tuần theo hai chữ số. Khoảng dữ liệu 2007-01 đến 2010-30. Quy ước đếm tuần là ISO 8601, như bạn có thể thấy ở đây on Wikipedia's "Week number" article, đôi khi đạt 53 tuần trong một năm. Ví dụ: 2009 có 53 tuần theo hệ thống này, xem số tuần trong this ISO 8601 calendar. (Xem các năm khác, theo bài viết trên Wikipedia, tuần thứ 53 là khá hiếm.)Tuần thứ 53 của năm trong R?

Về cơ bản tôi muốn đọc ngày trong tuần, chuyển đổi thành đối tượng Date và lưu nó vào một cột riêng biệt trong data.frame. Để kiểm tra, tôi đã hoàn nguyên các đối tượng Date thành yyyy-ww định dạng theo format([Date-object], format = "%Y-%W" và điều này đã xảy ra lỗi tại 2009-53. Tuần đó không được hiểu là một ngày theo số R. Điều này rất kỳ lạ, vì các năm khác làm không có tuần thứ 53 (theo tiêu chuẩn ISO 8601) được chuyển đổi tốt, chẳng hạn như 2007-53, trong khi các năm khác cũng không có tuần thứ 53 (theo tiêu chuẩn ISO 8601) cũng không thành công , chẳng hạn như 2008-53

Ví dụ tối thiểu sau đây minh họa sự cố.

Minimal dụ:

dates <- c("2009-50", "2009-51", "2009-52", "2009-53", "2010-01", "2010-02") 
as.Date(x = paste(dates, 1), format = "%Y-%W %w") 
# [1] "2009-12-14" "2009-12-21" "2009-12-28" NA   "2010-01-04" 
# [6] "2010-01-11" 

other.dates <- c("2007-53", "2008-53", "2009-53", "2010-53") 
as.Date(x = paste(other.dates, 1), format = "%Y-%W %w") 
# [1] "2007-12-31" NA   NA   NA  

Câu hỏi là, làm thế nào để tôi nhận được R để chấp nhận số tuần ở định dạng ISO 8601?

Lưu ý: Câu hỏi này tóm tắt sự cố tôi đã gặp phải trong vài giờ. Tôi đã tìm kiếm và tìm thấy các bài đăng hữu ích khác nhau như this, nhưng không ai giải quyết được vấn đề.

+1

Có thể minh họa hơn để so sánh 'as.Date (x =" 2009-01 01 ", định dạng ="% Y-% W% w ")' với 'ISOweek2date (" 2009-W01-1 ")' và bạn cũng nên trích dẫn mục nhập cho '% W' trong' help (strptime) '. – Roland

+0

Không chắc chắn, nhưng tôi nhớ rằng rất nhiều xử lý ngày của R thực sự được xử lý bởi thư viện hệ thống, điều này có nghĩa là loại sự cố này (a) sẽ thay đổi rất nhiều từ hệ điều hành sang hệ điều hành; (b) có thể đặc biệt dodgy trên Windows; (c) sẽ khó khắc phục trong bản thân R (như đã thấy trong câu trả lời dưới đây; 'ISOweek' thực hiện các thuật toán riêng của nó vì các công cụ bị thiếu trong thư viện hệ thống của Windows) –

+0

@BenBolker Hành vi được định nghĩa trong' help (strptime) ' . – Roland

Trả lời

10

Gói ISOweek quản lý các số tuần theo phong cách ISO 8601, chuyển đổi đến và từ Date đối tượng trong R. Xem ISOweek để biết thêm. Tiếp tục các ví dụ ngày ở trên, trước tiên chúng ta cần sửa đổi định dạng một chút. Họ phải ở dạng yyyy-Www-w thay vì yyyy-ww, tức là 2009-W53-1. Chữ số cuối cùng xác định ngày nào trong tuần để sử dụng trong việc xác định tuần, trong trường hợp này là thứ hai. Số tuần phải là hai chữ số.

library(ISOweek) 

dates <- c("2009-50", "2009-51", "2009-52", "2009-53", "2010-01", "2010-02") 
other.dates <- c("2007-53", "2008-53", "2009-53", "2010-53") 

dates <- sub("(\\d{4}-)(\\d{2})", "\\1W\\2-1", dates) 
other.dates <- sub("(\\d{4}-)(\\d{2})", "\\1W\\2-1", other.dates) 

## Check: 
dates 
# [1] "2009-W50-1" "2009-W51-1" "2009-W52-1" "2009-W53-1" "2010-W01-1" 
# [6] "2010-W02-1" 

(iso.date <- ISOweek2date(dates))    # deal correctly 
# [1] "2009-12-07" "2009-12-14" "2009-12-21" "2009-12-28" "2010-01-04" 
# [6] "2010-01-11" 
(iso.other.date <- ISOweek2date(other.dates)) # also deals with this 
# [1] "2007-12-31" "2008-12-29" "2009-12-28" "2011-01-03" 

## Check that back-conversion works: 
all(date2ISOweek(iso.date) == dates) 
# [1] TRUE 

## This does not work for the others, since the 53rd week of 
## e.g. 2008 is back-converted to the first week of 2009, in 
## line with the ISO 6801 standard. 
date2ISOweek(iso.other.date) == other.dates 
# [1] FALSE FALSE TRUE FALSE 
Các vấn đề liên quan