日期组件不会计算年份的变化
Date component will not calculate over change in Year
伙计,处理日期很难!!
我有以下数据,正在尝试应用 Tidyverse 原则并对日期组件使用 lubridate
dates <- data.frame(date = as.Date(c('2017-12-17',
'2017-12-28',
'2018-01-03',
'2018-01-19')))
我想为每个日期定义年份和一年中的星期几,这很简单。
new <- dates %>%
mutate(c_year = year(date),
c_week = week(date))
我真正想知道的是每个 'c_year' 的 'c_week' 开始的确切日期 (ymd)。但是,当我想计算 'c_week' 的开始时,我没有使用 floor_date() 的原始完整日期。所以我在互联网上四处寻找,发现这段代码(大部分)工作正常,可以计算新的 's_create_wk' 变量,顺便说一句,我希望星期一是一周的开始:
new <- dates %>%
mutate(c_year = year(date),
c_week = week(date),
s_create_wk = as.Date(paste0(c_year,c_week, "1"),
"%Y%W%u"))
所以理论上我应该得到:
date c_year c_week start_of_wk
1 2017-12-17 2017 51 2017-12-11
2 2017-12-28 2017 53 2017-12-25
3 2018-01-03 2018 1 2018-01-01
4 2018-01-19 2018 3 2018-01-15
但我实际得到的是:
date c_year c_week start_of_wk
1 2017-12-17 2017 51 2017-12-18
2 2017-12-28 2017 52 2017-12-25
3 2018-01-03 2018 1 NA
4 2018-01-19 2018 3 NA
查看我的 Outlook 日历,2017-12-25 应该在第 53 周,但无论我使用 'week()' 还是 'isoweek()',我都会得到如图所示的实际值。这令人困惑,因为第 51 周对于 2017 年 12 月 17 日的原始日期是正确的。此外,'start_of_wk' 计算 'c_week' 的时间晚了一周 - 这太令人困惑了。如果我减去 7 天,我得到 'c_week' 的正确 'start-of-wk',但这似乎是错误的做法。
长话短说,最大的问题是我在 'start_of_wk' 获得 2018 年日期的 NA,但我不知道为什么!!
抱歉,如果这让我感到困惑,但这肯定让我感到困惑。我猜是日期的格式在计算 's_create_wk' 时出错了,但我尝试了很多组合(Uu、Vv、Ww),或者我使用了错误的包或错误的函数来工作正确日期组件。
感谢您的帮助。
我认为这可以满足您的需求,尽管它需要额外的函数定义才能在管道中工作。 lubridate
有一个设置星期几的 wday
函数,特别是 wday(x) <- 1
会将日期 x
更改为该周的开始日期。参数 week_start
控制哪一天被视为一周的开始;在这里我选择星期一开始一周以适应您想要的输出。
编辑:为了解决关于第 2 行是第 52 周而不是第 53 周的部分,根据我的计算 2017-12-28
是第 52 周,无论您如何计算。例如,week(ymd("2017-12-30"))
是一年中的第 364 天,因此在第 52 周 (52 * 7 = 364),而 week(ymd("2012-12-31"))
returns 53 符合预期。
library(tidyverse)
dates <- tibble(date = c('2017-12-17', '2017-12-28', '2018-01-03', '2018-01-19'))
wk_start <- function(date){
wk_st <- date
wday(wk_st, week_start = 1) <- 1
return(wk_st)
}
dates %>%
mutate(date = ymd(date)) %>%
mutate(year = year(date),
week = week(date)
) %>%
mutate(start_of_wk = wk_start(date))
# A tibble: 4 x 4
date year week start_of_wk
<date> <dbl> <dbl> <date>
1 2017-12-17 2017 51.0 2017-12-11
2 2017-12-28 2017 52.0 2017-12-25
3 2018-01-03 2018 1.00 2018-01-01
4 2018-01-19 2018 3.00 2018-01-15
EDIT2:我四处寻找,我认为您的 as.Date
方法不起作用的原因是数字的间距不正确。查看 paste0(c_year, c_week, "1")
的结果。相反,这种插入垫片的类似方法确实提供了所需的输出,但第一行除外,我仍在考虑:
dates %>%
mutate(c_year = year(date),
c_week = week(date),
s_create_wk = as.Date(str_c(c_year, c_week, "1", sep = "-"), "%Y-%W-%u")
)
# A tibble: 4 x 4
date c_year c_week s_create_wk
<chr> <dbl> <dbl> <date>
1 2017-12-17 2017 51.0 2017-12-18
2 2017-12-28 2017 52.0 2017-12-25
3 2018-01-03 2018 1.00 2018-01-01
4 2018-01-19 2018 3.00 2018-01-15
伙计,处理日期很难!!
我有以下数据,正在尝试应用 Tidyverse 原则并对日期组件使用 lubridate
dates <- data.frame(date = as.Date(c('2017-12-17',
'2017-12-28',
'2018-01-03',
'2018-01-19')))
我想为每个日期定义年份和一年中的星期几,这很简单。
new <- dates %>%
mutate(c_year = year(date),
c_week = week(date))
我真正想知道的是每个 'c_year' 的 'c_week' 开始的确切日期 (ymd)。但是,当我想计算 'c_week' 的开始时,我没有使用 floor_date() 的原始完整日期。所以我在互联网上四处寻找,发现这段代码(大部分)工作正常,可以计算新的 's_create_wk' 变量,顺便说一句,我希望星期一是一周的开始:
new <- dates %>%
mutate(c_year = year(date),
c_week = week(date),
s_create_wk = as.Date(paste0(c_year,c_week, "1"),
"%Y%W%u"))
所以理论上我应该得到:
date c_year c_week start_of_wk
1 2017-12-17 2017 51 2017-12-11
2 2017-12-28 2017 53 2017-12-25
3 2018-01-03 2018 1 2018-01-01
4 2018-01-19 2018 3 2018-01-15
但我实际得到的是:
date c_year c_week start_of_wk
1 2017-12-17 2017 51 2017-12-18
2 2017-12-28 2017 52 2017-12-25
3 2018-01-03 2018 1 NA
4 2018-01-19 2018 3 NA
查看我的 Outlook 日历,2017-12-25 应该在第 53 周,但无论我使用 'week()' 还是 'isoweek()',我都会得到如图所示的实际值。这令人困惑,因为第 51 周对于 2017 年 12 月 17 日的原始日期是正确的。此外,'start_of_wk' 计算 'c_week' 的时间晚了一周 - 这太令人困惑了。如果我减去 7 天,我得到 'c_week' 的正确 'start-of-wk',但这似乎是错误的做法。
长话短说,最大的问题是我在 'start_of_wk' 获得 2018 年日期的 NA,但我不知道为什么!!
抱歉,如果这让我感到困惑,但这肯定让我感到困惑。我猜是日期的格式在计算 's_create_wk' 时出错了,但我尝试了很多组合(Uu、Vv、Ww),或者我使用了错误的包或错误的函数来工作正确日期组件。
感谢您的帮助。
我认为这可以满足您的需求,尽管它需要额外的函数定义才能在管道中工作。 lubridate
有一个设置星期几的 wday
函数,特别是 wday(x) <- 1
会将日期 x
更改为该周的开始日期。参数 week_start
控制哪一天被视为一周的开始;在这里我选择星期一开始一周以适应您想要的输出。
编辑:为了解决关于第 2 行是第 52 周而不是第 53 周的部分,根据我的计算 2017-12-28
是第 52 周,无论您如何计算。例如,week(ymd("2017-12-30"))
是一年中的第 364 天,因此在第 52 周 (52 * 7 = 364),而 week(ymd("2012-12-31"))
returns 53 符合预期。
library(tidyverse)
dates <- tibble(date = c('2017-12-17', '2017-12-28', '2018-01-03', '2018-01-19'))
wk_start <- function(date){
wk_st <- date
wday(wk_st, week_start = 1) <- 1
return(wk_st)
}
dates %>%
mutate(date = ymd(date)) %>%
mutate(year = year(date),
week = week(date)
) %>%
mutate(start_of_wk = wk_start(date))
# A tibble: 4 x 4
date year week start_of_wk
<date> <dbl> <dbl> <date>
1 2017-12-17 2017 51.0 2017-12-11
2 2017-12-28 2017 52.0 2017-12-25
3 2018-01-03 2018 1.00 2018-01-01
4 2018-01-19 2018 3.00 2018-01-15
EDIT2:我四处寻找,我认为您的 as.Date
方法不起作用的原因是数字的间距不正确。查看 paste0(c_year, c_week, "1")
的结果。相反,这种插入垫片的类似方法确实提供了所需的输出,但第一行除外,我仍在考虑:
dates %>%
mutate(c_year = year(date),
c_week = week(date),
s_create_wk = as.Date(str_c(c_year, c_week, "1", sep = "-"), "%Y-%W-%u")
)
# A tibble: 4 x 4
date c_year c_week s_create_wk
<chr> <dbl> <dbl> <date>
1 2017-12-17 2017 51.0 2017-12-18
2 2017-12-28 2017 52.0 2017-12-25
3 2018-01-03 2018 1.00 2018-01-01
4 2018-01-19 2018 3.00 2018-01-15