如何将日期时间转换为 R 中一周的第一个星期日
How to convert datetime to first Sunday of the week in R
目标:将日期对象转换为星期几的日期;它们仍应作为日期对象发挥作用
例如,今天将转换为 2016-10-16
,明天将转换为相同。
示例数据:
library(lubridate)
dt <- Sys.Date()-days(1:20)
"2016-10-17" "2016-10-16" "2016-10-15" "2016-10-14" "2016-10-13" "2016-10-12" "2016-10-11"
"2016-10-10" "2016-10-09" "2016-10-08" "2016-10-07" "2016-10-06" "2016-10-05"
"2016-10-04" "2016-10-03" "2016-10-02"
预期输出:
"2016-10-16" "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09"
"2016-10-09" "2016-10-09" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
"2016-10-02" "2016-10-02" "2016-10-02"
我试过 lubridate
、zoo
和 xts
包以及 strptime
,但没有什么能完全满足需要。 MySQL 中的函数 yearweek
正是我想要的(注意:包 sqldf
没有那个函数)。
这似乎已经有了答案,但没有找到答案; C++、javascript 和 Ruby,但 R 中没有。
此处不需要 lubridate。您可以改为执行类似以下的操作。
## `%w` returns weekday as number between 0 and 6, with 0 meaning "Sunday"
dt - as.numeric(strftime(dt, format="%w"))
# [1] "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09"
# [6] "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-02" "2016-10-02"
# [11] "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
# [16] "2016-09-25" "2016-09-25" "2016-09-25" "2016-09-25" "2016-09-25"
这是另一个从头到尾的解决方案——在此过程中的任何一步都不需要润滑:
R> dt <- Sys.Date() - 1:20
R> newdt <- dt - as.POSIXlt(dt)$wday
R> data.frame(dt, newdt)
dt newdt
1 2016-10-16 2016-10-16
2 2016-10-15 2016-10-09
3 2016-10-14 2016-10-09
4 2016-10-13 2016-10-09
5 2016-10-12 2016-10-09
6 2016-10-11 2016-10-09
7 2016-10-10 2016-10-09
8 2016-10-09 2016-10-09
9 2016-10-08 2016-10-02
10 2016-10-07 2016-10-02
11 2016-10-06 2016-10-02
12 2016-10-05 2016-10-02
13 2016-10-04 2016-10-02
14 2016-10-03 2016-10-02
15 2016-10-02 2016-10-02
16 2016-10-01 2016-09-25
17 2016-09-30 2016-09-25
18 2016-09-29 2016-09-25
19 2016-09-28 2016-09-25
20 2016-09-27 2016-09-25
R>
在 [quickref zoo vignette] 中有一个单行函数 nextfri
给出下周五。我们可以很容易地对其进行修改——将星期五的 5 替换为星期日的 0,并将 ceiling
替换为 floor
以获得最后一个而不是下一个。使用问题中显示的输入(并在末尾的注释中重复显示),我们得到以下结果。请注意,必须加载 zoo 包才能工作。
library(zoo)
lastsun <- function(x) 7 * floor(as.numeric(x-0+4) / 7) + as.Date(0-4)
lastsun(x)
给予:
[1] "2016-10-16" "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09"
[6] "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-02"
[11] "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
[16] "2016-10-02"
或进一步简化我们得到这个 不需要加载动物园并给出相同的输出:
lastsun2 <- function(x) x - as.numeric(x+4) %% 7
lastsun2(x)
注:输入x
使用的是:
x <- as.Date(c("2016-10-17", "2016-10-16", "2016-10-15", "2016-10-14", "2016-10-13",
"2016-10-12", "2016-10-11", "2016-10-10", "2016-10-09", "2016-10-08", "2016-10-07",
"2016-10-06", "2016-10-05", "2016-10-04", "2016-10-03", "2016-10-02"))
目标:将日期对象转换为星期几的日期;它们仍应作为日期对象发挥作用
例如,今天将转换为 2016-10-16
,明天将转换为相同。
示例数据:
library(lubridate)
dt <- Sys.Date()-days(1:20)
"2016-10-17" "2016-10-16" "2016-10-15" "2016-10-14" "2016-10-13" "2016-10-12" "2016-10-11"
"2016-10-10" "2016-10-09" "2016-10-08" "2016-10-07" "2016-10-06" "2016-10-05"
"2016-10-04" "2016-10-03" "2016-10-02"
预期输出:
"2016-10-16" "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09"
"2016-10-09" "2016-10-09" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
"2016-10-02" "2016-10-02" "2016-10-02"
我试过 lubridate
、zoo
和 xts
包以及 strptime
,但没有什么能完全满足需要。 MySQL 中的函数 yearweek
正是我想要的(注意:包 sqldf
没有那个函数)。
这似乎已经有了答案,但没有找到答案; C++、javascript 和 Ruby,但 R 中没有。
此处不需要 lubridate。您可以改为执行类似以下的操作。
## `%w` returns weekday as number between 0 and 6, with 0 meaning "Sunday"
dt - as.numeric(strftime(dt, format="%w"))
# [1] "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09"
# [6] "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-02" "2016-10-02"
# [11] "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
# [16] "2016-09-25" "2016-09-25" "2016-09-25" "2016-09-25" "2016-09-25"
这是另一个从头到尾的解决方案——在此过程中的任何一步都不需要润滑:
R> dt <- Sys.Date() - 1:20
R> newdt <- dt - as.POSIXlt(dt)$wday
R> data.frame(dt, newdt)
dt newdt
1 2016-10-16 2016-10-16
2 2016-10-15 2016-10-09
3 2016-10-14 2016-10-09
4 2016-10-13 2016-10-09
5 2016-10-12 2016-10-09
6 2016-10-11 2016-10-09
7 2016-10-10 2016-10-09
8 2016-10-09 2016-10-09
9 2016-10-08 2016-10-02
10 2016-10-07 2016-10-02
11 2016-10-06 2016-10-02
12 2016-10-05 2016-10-02
13 2016-10-04 2016-10-02
14 2016-10-03 2016-10-02
15 2016-10-02 2016-10-02
16 2016-10-01 2016-09-25
17 2016-09-30 2016-09-25
18 2016-09-29 2016-09-25
19 2016-09-28 2016-09-25
20 2016-09-27 2016-09-25
R>
在 [quickref zoo vignette] 中有一个单行函数 nextfri
给出下周五。我们可以很容易地对其进行修改——将星期五的 5 替换为星期日的 0,并将 ceiling
替换为 floor
以获得最后一个而不是下一个。使用问题中显示的输入(并在末尾的注释中重复显示),我们得到以下结果。请注意,必须加载 zoo 包才能工作。
library(zoo)
lastsun <- function(x) 7 * floor(as.numeric(x-0+4) / 7) + as.Date(0-4)
lastsun(x)
给予:
[1] "2016-10-16" "2016-10-16" "2016-10-09" "2016-10-09" "2016-10-09"
[6] "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-09" "2016-10-02"
[11] "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02" "2016-10-02"
[16] "2016-10-02"
或进一步简化我们得到这个 不需要加载动物园并给出相同的输出:
lastsun2 <- function(x) x - as.numeric(x+4) %% 7
lastsun2(x)
注:输入x
使用的是:
x <- as.Date(c("2016-10-17", "2016-10-16", "2016-10-15", "2016-10-14", "2016-10-13",
"2016-10-12", "2016-10-11", "2016-10-10", "2016-10-09", "2016-10-08", "2016-10-07",
"2016-10-06", "2016-10-05", "2016-10-04", "2016-10-03", "2016-10-02"))