【问题标题】:How to convert datetime to first Sunday of the week in R如何在R中将日期时间转换为一周的第一个星期日
【发布时间】:2016-10-17 21:58:00
【问题描述】:

目标:将日期对象转换为星期几的日期;它们仍应用作日期对象

例如,今天将转换为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"

我尝试过使用lubridatezooxts 包和strptime,但没有什么能满足需要。 MySQL 中的函数yearweek 正是我想要的(注意:包sqldf 没有那个函数)。

这似乎已经有了答案,但搜索却没有运气; C++、javascript 和 Ruby,但在 R 中什么都没有。

【问题讨论】:

  • 你检查过floor_date(dt, "week")吗?
  • dt - ((lubridate::wday(dt) + 5) %% 7 + 1)
  • “一周的第一个星期日”..?
  • @lukeA 这是一个很方便的功能,有什么方法可以选择楼层设置在哪一天?
  • @bigreddmachine 我的错字,我的错。不用担心!

标签: r datetime data-conversion


【解决方案1】:

这里不需要 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"

【讨论】:

  • 我通过减去POSIXltwday 字段来使用数字调整有类似的东西。
【解决方案2】:

这是从头到尾的另一种解决方案 - 在此过程中的任何步骤都不需要润滑:

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> 

【讨论】:

  • 很高兴提醒POSIXlt 对象产生我通常想要的整数和数值。
  • 也非常有用,更简洁。我喜欢这本质上是一个单一的电话。据记录,这比 @JoshO'Brien 的 strftime 解决方案快了约 10 倍。
  • 感谢您安排时间。我也有同样的想法——如果有疑问,请避免文本表示和重新分析。
【解决方案3】:

[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"))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-14
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2019-09-19
    • 2018-01-29
    相关资源
    最近更新 更多