2016-07-26 154 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 
结果
相关问题