【问题标题】:R: Round down dates to first day of the weekR:将日期向下舍入到一周的第一天
【发布时间】:2017-05-05 20:25:18
【问题描述】:

我有一个数据框,其中一列包含日期(某些日期出现多次)。我想按周汇总日期。我能想到的最好方法是将日期四舍五入到最近的星期一。我怎样才能四舍五入日期?如何将此日期列表转换为周?

2016-04-04
2016-04-05
2016-04-06
2016-04-07
2016-04-08
2016-04-09
2016-04-10
2016-04-11
2016-04-12
2016-04-13
2016-04-14

预期的输出应该是这样的:

2016-04-04
2016-04-04
2016-04-04
2016-04-04
2016-04-04
2016-04-04
2016-04-04
2016-04-11
2016-04-11
2016-04-11
2016-04-11

【问题讨论】:

  • 似乎this 可以提供帮助。
  • 你可以从你的日期中减去wdaylubridatedata.table 有这个函数的实现。
  • cut.Date() 默认情况下每周一开始。 lubridatedata.table 从星期日开始。
  • @uwe-block 谢谢,完美。我刚试过cut.POSIXt(table$date, breaks = "week") 并且可以工作。 (我的日期存储为 POSIXct)

标签: r


【解决方案1】:

来自基 R 的cut() 有两个方法用于 DatePOSIXt 类的对象,它们假定默认情况下每周从星期一开始(但可以使用 start.on.monday = FALSE 更改为星期日)。

dates <- c("2016-04-04", "2016-04-05", "2016-04-06", "2016-04-07", "2016-04-08", 
           "2016-04-09", "2016-04-10", "2016-04-11", "2016-04-12", "2016-04-13", 
           "2016-04-14")
result <- data.frame(
  dates,
  cut_Date = cut(as.Date(dates), "week"),
  cut_POSIXt = cut(as.POSIXct(dates), "week"),
  stringsAsFactors = FALSE)

result
#        dates   cut_Date cut_POSIXt
#1  2016-04-04 2016-04-04 2016-04-04
#2  2016-04-05 2016-04-04 2016-04-04
#3  2016-04-06 2016-04-04 2016-04-04
#4  2016-04-07 2016-04-04 2016-04-04
#5  2016-04-08 2016-04-04 2016-04-04
#6  2016-04-09 2016-04-04 2016-04-04
#7  2016-04-10 2016-04-04 2016-04-04
#8  2016-04-11 2016-04-11 2016-04-11
#9  2016-04-12 2016-04-11 2016-04-11
#10 2016-04-13 2016-04-11 2016-04-11
#11 2016-04-14 2016-04-11 2016-04-11

请注意,cut() 返回的因子非常适合 OP 要求的聚合:

str(result)
#'data.frame':  11 obs. of  3 variables:
# $ dates     : chr  "2016-04-04" "2016-04-05" "2016-04-06" "2016-04-07" ...
# $ cut_Date  : Factor w/ 2 levels "2016-04-04","2016-04-11": 1 1 1 1 1 1 1 2 2 2 ...
# $ cut_POSIXt: Factor w/ 2 levels "2016-04-04","2016-04-11": 1 1 1 1 1 1 1 2 2 2 ...

但是,对于使用 ggplot2 绘制聚合值(如果有大量周数可能会使轴混乱),最好从离散时间尺度切换到连续时间尺度。那么就需要将因子强制回DatePOSIXct

as.Date(as.character(result$cut_Date))
as.POSIXct(as.character(result$cut_Date))

【讨论】:

  • cut(as.POSIXct(dates), "week") 可能会返回星期日而不是星期一,我认为这是时区问题
【解决方案2】:

使用lubridate 包的floor_date 函数中的week_start 参数,您可以选择指定自lubridate version 1.7.0 以来的一周的开始时间。这允许您执行:

library(lubridate)
dates <- seq.Date(as.Date("2016-04-04"), as.Date("2016-04-14"), by = 1)
floor_date(dates, "weeks", week_start = 1)

我会将其发布为对 Sraffa 回复的评论,但我没有声誉。

【讨论】:

    【解决方案3】:

    使用lubridate 你可以试试这个:

    library(lubridate)
    dates <- seq.Date(as.Date("2016-04-04"), as.Date("2016-04-14"), by = 1)
    floor_date(dates - 1, "weeks") + 1
    

    floor_date 每周日开始计算,因此为避免包含在下周中,您必须在四舍五入前减去 1,然后将值增加 1 天。

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多