2016-07-26 148 views
1

我最近遇到了R處理日期的問題。 2015年的最後一天(2015-12-31)是週四,意味着如果我把星期天定爲本週的開始日,那麼上一週只有5天。現在,我希望在週五和週六的2016-01-01和2016-01-02與第53周相關,並在2016-01-03開始的第1周,這個週日將在週日舉行。開始星期日的第一週的星期幾,星期六的星期的最後一天結束

require(lubridate) 
range <- seq(as.Date('2015-12-26'), by = 1, len = 10) 
df <- data.frame(range) 
df$WKN <- as.numeric(strftime(df$range, format = "%U")) + 1 
df$weekday <- weekdays(df$range) 
df$weeknum <- wday(df$range) 

這會給我以下結果:

df: 
range  WKN weekday weeknum 
2015-12-26 52 Saturday  7 
2015-12-27 53 Sunday  1 
2015-12-28 53 Monday  2 
2015-12-29 53 Tuesday  3 
2015-12-30 53 Wednesday  4 
2015-12-31 53 Thursday  5 
2016-01-01 1 Friday  6 
2016-01-02 1 Saturday  7 
2016-01-03 2 Sunday  1 
2016-01-04 2 Monday  2 

現在我想有我數據框如下:

df: 
range  WKN weekday weeknum 
2015-12-26 52 Saturday  7 
2015-12-27 53 Sunday  1 
2015-12-28 53 Monday  2 
2015-12-29 53 Tuesday  3 
2015-12-30 53 Wednesday  4 
2015-12-31 53 Thursday  5 
2016-01-01 53 Friday  6 
2016-01-02 53 Saturday  7 
2016-01-03 1 Sunday  1 
2016-01-04 1 Monday  2 

任何人都可以點我的方向自動執行以便我不必每年都更改代碼?

回答

1

使用cumsum如果你看看?strptime,有可與format使用幾個不同的週數令牌。這裏%V差不多的作品,但它開始的一週,週一,所以加一個調整:

df$WKN <- as.integer(format(df$range + 1, '%V')) 

df 
##   range WKN weekday weeknum 
## 1 2015-12-26 52 Saturday  7 
## 2 2015-12-27 53 Sunday  1 
## 3 2015-12-28 53 Monday  2 
## 4 2015-12-29 53 Tuesday  3 
## 5 2015-12-30 53 Wednesday  4 
## 6 2015-12-31 53 Thursday  5 
## 7 2016-01-01 53 Friday  6 
## 8 2016-01-02 53 Saturday  7 
## 9 2016-01-03 1 Sunday  1 
## 10 2016-01-04 1 Monday  2 

或者,如果你使用dplyr像標籤表明,

library(dplyr) 

df %>% mutate(WKN = as.integer(format(range + 1, '%V'))) 

返回同樣的事情。 lubridate的isoweek功能都是等價的,所以你也可以做

library(lubridate) 

df$WKN <- isoweek(df$range + 1) 

df %>% mutate(WKN = isoweek(range + 1)) 

兩者返回相同的結果爲as.integer(format(...))版本。

1

我們可以在邏輯向量

df$WKN <- unique(df$WKN)[cumsum(df$weeknum==1) +1] 
df$WKN 
#[1] 52 53 53 53 53 53 53 53 1 1 
1

考慮到您正在使用lubridate,我也想給你一個潤滑的解決方案。您還要求提供適用於其他年份的解決方案。這裏所說:

adjust_first_week<- function(year){ 

    first <- floor_date(dmy(paste0("1-1-", year)), "year") 
    two_weeks <- c(first - days(7:1), first + days(0:6)) 

    df <- data.frame(date = two_weeks, 
       day_of_week = weekdays(two_weeks), 
       day_of_year = yday(two_weeks), 
       week_of_year = week(two_weeks)) 

    last_weekend <- which(df$day_of_week == "Sunday")[2] -1 
    df$adjust_week <- df$week_of_year 
    if(last_weekend ==7) return(df) 
    else{ 
     df$adjust_week[8:last_weekend] <- rep(53,length(8:last_weekend)) 
    } 
    return(df) 
    } 
  1. 注意到一個數字的一​​年,並採取一年的第一天。
  2. 通過在1/1 /年的任一側附加一週來創建兩週的時間段。
  3. 計算您的啓蒙當年的各種彙總統計。
  4. 推出第二個星期天。按設計1/1 /年總是第8條。
  5. 如果星期日是本月的第一天,它什麼都不會做。
  6. 否則它將覆蓋一年中的某一週,以便一年中的第一週從第二個星期日開始。

這裏是

adjust_last_week(2016) 
     date day_of_week day_of_year week_of_year adjust_week 
1 2015-12-25  Friday   359   52   52 
2 2015-12-26 Saturday   360   52   52 
3 2015-12-27  Sunday   361   52   52 
4 2015-12-28  Monday   362   52   52 
5 2015-12-29  Tuesday   363   52   52 
6 2015-12-30 Wednesday   364   52   52 
7 2015-12-31 Thursday   365   53   53 
8 2016-01-01  Friday   1   1   53 
9 2016-01-02 Saturday   2   1   53 
10 2016-01-03  Sunday   3   1   1 
11 2016-01-04  Monday   4   1   1 
12 2016-01-05  Tuesday   5   1   1 
13 2016-01-06 Wednesday   6   1   1 
14 2016-01-07 Thursday   7   1   1 
結果
相關問題