将年/周转换为日期对象 [英] Transform year/week to date object

查看:45
本文介绍了将年/周转换为日期对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

字符串包含YEAR WEEK",我想用 parse_date_time() 将其转换为日期对象,但我无法使代码工作:

parse_date_time(c("201510"), "YW")

我不必使用lubridate,其他包也可以.

解决方案

在将年-周转换为日期之前,您必须指定一周中的哪一天,但更重要的是您必须确保不同的约定 正在被使用.

Base R 的 strptime() 函数知道 一年中的第 3 个星期的定义(但在输入时仅支持其中 2 个)和 星期几的 2 个定义,见 ?strptime:

一年中的一周

  • 美国惯例:一年中的第几周作为十进制数 (00–53),使用星期日作为一周的第一天(通常将一年中的第一个星期日作为第 1 天)第 1 周第 1):%U

  • 英国惯例:以十进制数 (00–53) 表示的一年中的周,使用星期一作为一周的第一天(通常将一年中的第一个星期一作为第 1 天)第 1 周):%W

  • ISO 8601 定义:ISO 8601 中定义的十进制数 (01–53) 表示的一年中的周.如果包含 1 月 1 日的周(从星期一开始)有四个或更多新年的第几天,那么它被认为是第 1 周.否则,它是上一年的最后一周,下一周是第 1 周:%V 被接受但在输入时被忽略.
    请注意,还有一个基于周的年份(%G%g)与 %V 一起使用,因为它可能不同来自日历年(%Y%y).

数字工作日

  • 工作日为十进制数(1-7,星期一为 1):%u
  • 工作日为十进制数(0-6,星期日为 0):%w
  • 有趣的是,周日算作一周中的第 1 天的情况没有格式.

用不同的约定转换年-周-日

如果我们将第 1 天附加到字符串并使用我们得到的不同格式

as.Date("2015101", "%Y%U%u")# [1] 《2015-03-09》as.Date("2015101", "%Y%U%w")# [1] 《2015-03-09》as.Date("2015101", "%Y%W%u")# [1] 《2015-03-09》as.Date("2015101", "%Y%W%w")# [1] 《2015-03-09》as.Date("2015101", "%G%V%u")# [1] 不适用

对于工作日格式 %u%w,我们确实得到了相同的结果,因为在这两种约定中,第 1 天是星期一(但在处理星期日时要小心).

对于 2015 年,美国和英国对一年中第几周的定义是一致的,但并非所有年份都如此,例如,2001、2007 和 2018 年并非如此:

as.Date("2018101", "%Y%U%u")#[1]2018-03-12"as.Date("2018101", "%Y%W%u")#[1]2018-03-05"

输入不支持 ISO 8601 格式说明符.因此,我创建了 ISOweek 几年前:

ISOweek::ISOweek2date(2015-W10-1")#[1]2015-03-02"

使用星期四将一周与一个月相关联

如上所述,您需要指定一周中的哪一天才能获得完整的日历日期.如果需要按月汇总日期,这也是必需的.

如果没有指定工作日,并且如果日期应该按月汇总,您可以将每周的星期四作为参考日(以下 djhurio 的建议).这可确保将整周分配给一周中大部分天数所属的月份.

例如,以星期日为参考日会返回

ISOweek::ISOweek2date(2015-W09-7")

<块引用>

[1] "2015-03-01";

因此会将整周与三月相关联,尽管一周中只有一天属于三月,而其他 6 天属于二月.以星期四为参考日将返回二月的日期:

ISOweek::ISOweek2date(2015-W09-4")

<块引用>

[1] "2015-02-26";

String contains 'YEAR WEEK' and I want to transform it with parse_date_time() to a date object but I can't make the code work:

parse_date_time(c("201510"), "YW")

I don't have to use lubridate, can be other packages, too.

解决方案

Before converting year-week to a date you have to specify a day of the week but more importantly you have to ensure which of the different conventions is being used.

Base R's strptime() function knows 3 definitions of week of the year (but supports only 2 of them on input) and 2 definitions of weekday number, see ?strptime:

Week of the year

  • US convention: Week of the year as decimal number (00–53) using Sunday as the first day 1 of the week (and typically with the first Sunday of the year as day 1 of week 1): %U

  • UK convention: Week of the year as decimal number (00–53) using Monday as the first day of week (and typically with the first Monday of the year as day 1 of week 1): %W

  • ISO 8601 definition: Week of the year as decimal number (01–53) as defined in ISO 8601. If the week (starting on Monday) containing 1 January has four or more days in the new year, then it is considered week 1. Otherwise, it is the last week of the previous year, and the next week is week 1: %V which is accepted but ignored on input.
    Note that there is also a week-based year (%G and %g) which is to be used with %V as it may differ from the calendar year (%Y and %y).

Numeric weekday

  • Weekday as a decimal number (1–7, Monday is 1): %u
  • Weekday as decimal number (0–6, Sunday is 0): %w
  • Interestingly, there is no format for the case Sunday is counted as day 1 of the week.

Converting year-week-day with the different conventions

If we append day 1 to the string and use the different formats we do get

as.Date("2015101", "%Y%U%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%U%w")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%w")
# [1] "2015-03-09"
as.Date("2015101", "%G%V%u")
# [1] NA

For weekday formats %u and %w we do get the same result because day 1 is Monday in both conventions (but watch out when dealing with Sundays).

For 2015, the US and the UK definition for week of the year coincide but this is not true for all years, e.g., not for 2001, 2007, and 2018:

as.Date("2018101", "%Y%U%u")
#[1] "2018-03-12"
as.Date("2018101", "%Y%W%u")
#[1] "2018-03-05"

The ISO 8601 format specifiers aren't supported on input. Therefore, I had created the ISOweek package some years ago:

ISOweek::ISOweek2date("2015-W10-1")
#[1] "2015-03-02"

Edit: Using Thursday to associate a week with a month

As mentioned above you need to specify a day of the week to get a full calendar date. This is also required if the dates need to be aggregated by month later on.

If no weekday is specified and if the dates are supposed to be aggregated by month later on, you may take the Thursday of each week as reference day (following a suggestion by djhurio). This ensures that the whole week is assigned to the month to which the majority of the days of the week belong to.

For example, taking Sunday as reference day would return

ISOweek::ISOweek2date("2015-W09-7")

[1] "2015-03-01"

which consequently would associate the whole week to the month of March although only one day of the week belongs to March while the other 6 days belong to February. Taking Thursday as reference day will return a date in February:

ISOweek::ISOweek2date("2015-W09-4")

[1] "2015-02-26"

这篇关于将年/周转换为日期对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆