简体   繁体   English

从星期日开始一年中的第一天,并在星期六结束一年中的最后一天

[英]Start first day of week of the year on Sunday and end last day of week of the year on Saturday

I have recently encountered a problem in R dealing with the dates. 我最近遇到了R处理日期的问题。 The last day of 2015 (2015-12-31) falls on Thursday, meaning last week of the year only contains 5 days if I consider Sunday as the start day of my week. 2015年(2015-12-31)的最后一天是星期四,这意味着如果我将星期日视为我一周的开始日,那么今年的最后一周只包含5天。 Now, I would like 2016-01-01 and 2016-01-02, which fall on Friday and Saturday, to be associated with week 53, and start week 1 on 2016-01-03, which falls on Sunday. 现在,我希望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)

This would give me the following result: 这会给我以下结果:

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

Now I would like to have my dataframe as follows: 现在我希望我的数据帧如下:

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

Could anyone point me to a direction to automate that so that I don't have to change the code every year? 任何人都可以指出我自动化的方向,以便我不必每年更改代码吗?

We can use cumsum on a logical vector 我们可以在逻辑向量上使用cumsum

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

If you check out ?strptime , there are a few different week number tokens available for use with format . 如果您查看?strptime ,有一些不同的周数令牌可用于format Here %V almost works, except it starts the week on Monday, so add one to adjust: 这里%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

Or if you're using dplyr like the tag suggests, 或者如果你像标签建议那样使用dplyr,

library(dplyr)

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

which returns the same thing. 它返回相同的东西。 The isoweek function of lubridate is equivalent, so you could also do isoweek功能是等价的,所以你也可以这样做

library(lubridate)

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

or 要么

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

both of which return identical results to the as.integer(format(...)) versions. 两者都返回与as.integer(format(...))版本相同的结果。

Considering that you are using lubridate , I also wanted to give you a lubridate solution. 考虑到你正在使用lubridate ,我也想给你一个润滑的解决方案。 You also asked for a solution that works with other years. 您还要求提供适用于其他年份的解决方案。 Here goes: 开始:

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. Takes a numeric year, and takes the first day of that year. 需要一个数字年份,并采取该年的第一天。
  2. Creates a two week period by appending a week on either side of 1/1/year. 通过在1/1 /年的任一侧附加一周来创建两周的时间段。
  3. Calculates various summary statistics for that year for your edification. 为您的启发计算该年度的各种摘要统计信息。
  4. Picks out the second Sunday. 挑出第二个星期天。 By design 1/1/year is always the 8th entry. 按设计1/1 /年始终是第8项。
  5. If Sunday is the first day of the month, it doesn't do anything. 如果星期日是这个月的第一天,它什么都不做。
  6. Otherwise it overwrites the week of the year so that the first week of the year starts on the second Sunday. 否则它会覆盖一年中的一周,以便一年中的第一周从第二个星期日开始。

Here is the results for 这是结果

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM