我有一个包含位置和日期的数据集。我想计算一年中的周数(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函数可用于计算一年中的一周,但只能使用星期一或星期日作为一周的第一天。 任何帮助都将受到高度赞赏。
答案 0 :(得分:22)
只需在日期格式化值中添加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。 (从根本上说,日期格式化值是从“原点”开始的整数序列,因此它们不会真正识别数年或数周。添加4只会移动基础日期整数的参考框架。)
编辑备注。根据Gabor的建议改为三个策略。 ....这仍然没有解决如何处理上一年的最后一周的问题。
答案 1 :(得分:2)
由于问题表明周从00-53开始,我们假设周数是相关日期或之前的一年中的星期四数。因此,一年中的第一个星期四从第1周开始,第0周被分配到该之前的任何日子。
(有评论说,如果一年的第一天是星期二那么那将是第1周,但如果是这样的话,那么在主题中似乎不需要一周0,所以对于可能需要定义周数。这里我们将使用前一段中的定义,但如果我们知道定义是什么就不难改变它。例如,如果我们总是希望第一周即使是短暂的一周,这一年也是1,那么我们可以在结果中添加!is.thu(jan1(d))
。)
以下两种解决方案都足够短,可以在一个声明中表达;但是,为了清楚起见,我们将它们分解为几个简短的函数。第一个是特别直接的,但第二个是自动矢量化而不需要sapply
,并且可能更有效。
<强> 1。总和星期四此解决方案假设输入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。 nextthu 强>
根据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
ADDED:在第二个解决方案中修复了错误。