从星期日开始一年中一周的第一天,在星期六结束一年中一周的最后一天
Start first day of week of the year on Sunday and end last day of week of the year on Saturday
我最近在 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
任何人都可以指出一个方向来实现自动化,这样我就不必每年更改代码了吗?
我们可以在逻辑向量
上使用 cumsum
df$WKN <- unique(df$WKN)[cumsum(df$weeknum==1) +1]
df$WKN
#[1] 52 53 53 53 53 53 53 53 1 1
如果您查看 ?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')))
这return是一回事。 lubridate 的 isoweek
功能是等价的,所以你也可以做
library(lubridate)
df$WKN <- isoweek(df$range + 1)
或
df %>% mutate(WKN = isoweek(range + 1))
两者 return 与 as.integer(format(...))
版本的结果相同。
考虑到你用的是lubridate
,我也想给你一个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/1/year 的两边添加一周来创建一个两周的时间段。
- 计算当年的各种汇总统计数据以供您启迪。
- 挑出第二个星期天。按照设计,1/1/年始终是第 8 个条目。
- 如果星期日是该月的第一天,它不会执行任何操作。
- 否则它会覆盖一年中的第几周,以便一年中的第一周从第二个星期日开始。
这是
的结果
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
我最近在 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
任何人都可以指出一个方向来实现自动化,这样我就不必每年更改代码了吗?
我们可以在逻辑向量
上使用cumsum
df$WKN <- unique(df$WKN)[cumsum(df$weeknum==1) +1]
df$WKN
#[1] 52 53 53 53 53 53 53 53 1 1
如果您查看 ?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')))
这return是一回事。 lubridate 的 isoweek
功能是等价的,所以你也可以做
library(lubridate)
df$WKN <- isoweek(df$range + 1)
或
df %>% mutate(WKN = isoweek(range + 1))
两者 return 与 as.integer(format(...))
版本的结果相同。
考虑到你用的是lubridate
,我也想给你一个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/1/year 的两边添加一周来创建一个两周的时间段。
- 计算当年的各种汇总统计数据以供您启迪。
- 挑出第二个星期天。按照设计,1/1/年始终是第 8 个条目。
- 如果星期日是该月的第一天,它不会执行任何操作。
- 否则它会覆盖一年中的第几周,以便一年中的第一周从第二个星期日开始。
这是
的结果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