【问题标题】:Calculate the week number (0-53) in year计算年份中的周数(0-53)
【发布时间】:2013-02-23 01:27:41
【问题描述】:

我有一个包含位置和日期的数据集。我想将一年中的星期计算为数字(00-53),但使用星期四作为一周的第一天。数据如下所示:

  location <- c(a,b,a,b,a,b)
  date <- c("04-01-2013","26-01-2013","03-02-2013","09-02-2013","20-02-2013","03-03-2013")
  mydf <- data.frame(location, date)
  mydf

我知道有 strftime 函数来计算一年中的星期,但只能使用星期一或星期日作为一周的第一天。 任何帮助将不胜感激。

【问题讨论】:

  • 如果我可以问你为什么要这样做?
  • 那么如果一年从周二开始,那么第一周是周二/周三,第二周从周四开始...?
  • 是的。一周应该是从周二到周三。
  • @joran ;星期编号的 strftime 约定是 0-53。 (与 R 中的其他索引不同。)
  • @joran: 所以如果一年从周二开始,那么第 0 周是周二/周三,第 1 周从周四开始

标签: r date-arithmetic week-number


【解决方案1】:

只需将 4 添加到日期格式的值:

> mydf$Dt <- as.Date(mydf$date, format="%d-%m-%Y")
> weeknum <- as.numeric( format(mydf$Dt+3, "%U"))
> weeknum
[1] 1 4 5 6 7 9

这使用基于 0 的计数约定,因为这是 strftime 提供的内容,我们只是捎带该代码库,因此从周二开始的一年中的第一个周五(如 2013 年的情况)将是 1 周的结果.如果您想要一个基于 1 的约定,则将该值加 1。 (从根本上说,日期格式的值是从“原点”开始的整数序列,因此它们不能真正识别年或周。添加 4 只会移动基础日期整数的参考框架。)

编辑注释。根据 Gabor 的建议更改为添加三个策略。 ....这仍然没有解决如何处理前一年的最后一周的问题。

【讨论】:

  • 关于周数的定义有一些疑问,但无论如何在问题中的 6 个日期之前的一年中有 1、4、5、6、7、9 个星期四,分别,这就提出了答案中的 8 是否正确的问题。 format(as.Date("2013-12-31")+4, "%U") 也给出 00。
  • “add-4”策略在星期四创建增量,因此星期四的计数与“add-3”策略一致。
  • 解决年终问题的方法可能是在 12 月减去 7 天,然后将周数加 1:ifelse(months(d) == "December", as.numeric(format(d-4, "%U"))+1, as.numeric(format(d+3, "%U")))
【解决方案2】:

由于问题表明周从 00 到 53,我们假设周数是相关日期或之前一年中的星期四数。因此,一年中的第一个星期四从第 1 周开始,第 0 周被分配到之前的任何日子。

(有 cmets 表示,如果一年中的第一天是星期二,那将是第 1 周,但如果是这种情况,则永远不可能有第 0 周,这似乎是该主题所要求的,因此请澄清一下究竟是什么可能需要星期数的定义。这里我们将使用上一段中的定义,但是如果我们知道定义是什么就不会很难改变它。例如,如果我们总是想要第一周在年份为 1,即使是很短的一周,我们也可以将 !is.thu(jan1(d)) 添加到结果中。)

以下两个解决方案都足够短,可以用一个语句来表达;但是,为了清楚起见,我们将它们分解为几个简短的函数。第一个特别简单,但第二个自动矢量化,无需sapply,可能会更有效。

1. sum Thursdays in year 此解决方案假定输入 d 属于 "Date" 类,并且只是将前一年或上一年的星期四数相加:

is.thu <- function(x) weekdays(x) == "Thursday"
jan1 <- function(x) as.Date(cut(x, "year"))

week4 <- function(d) {
  sapply(d, function(d) sum(is.thu(seq(jan1(d), d, by = "day"))))
}

我们可以这样测试:

d <- as.Date(c("2013-01-04", "2013-01-26", "2013-02-03", "2013-02-09", 
    "2013-02-20", "2013-03-03"))
week4(d) # 1 4 5 6 7 9

2。接下来

基于zoo quickref vignette 中的nextfri 函数,我们看到自下一个星期四(或相关日期,如果它已经是星期四)的纪元(1970-01-01)以来的天数为由nextthu 在下面的第一行给出。将此应用于一年的第一天,我们得出d 与以前一样的结果:

nextthu <- function(d) 7 * ceiling(as.numeric(d) / 7)

week4a <- function(d) (as.numeric(d) - nextthu(jan1(d))) %/% 7 + 1

这是一个测试

week4a(d) # 1 4 5 6 7 9

添加:修复了第二个解决方案中的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多