【问题标题】:Extract the months that fall in a lubridate interval提取属于润滑间隔的月份
【发布时间】:2017-10-23 21:29:31
【问题描述】:

给定一个润滑间隔,例如:

start <- "2016-09-24"
finish <- "2016-11-02"
my_interval <- lubridate::interval(start, finish)
my_interval

> my_interval
[1] 2016-09-24 UTC--2016-11-02 UTC

我希望能够提取属于此间隔的月份,在这种情况下:

[1] "Sep" "Oct" "Nov"

到目前为止,我在这方面的最佳尝试确实很笨拙:

my_months <- list(
  "Aug" = interval("2016-08-01", "2016-08-31"), 
  "Sep" = interval("2016-09-01", "2016-09-30"), 
  "Oct" = interval("2016-10-01", "2016-10-31"), 
  "Nov" = interval("2016-11-01", "2016-11-30"), 
  "Dec" = interval("2016-12-01", "2016-12-31")
)

extract_months <- function(x, months) {
  out <- vector(mode = "character")

  for (i in seq_along(months)) {
    in_month <- int_overlaps(x, months[[i]])
    if (in_month) {
      out[i] <- names(months)[i]
    }
    out <- out[!is.na(out)]
  }
  out
}

extract_months(x = my_interval, months = my_months)

> extract_months(x = my_interval, months = my_months)
[1] "Sep" "Oct" "Nov"

多年来,这很快就会变得笨拙。我希望有人有更好的解决方案。

我看不出这个问题与Subset a dataframe between 2 dates的重复

【问题讨论】:

标签: r lubridate


【解决方案1】:

其实很简单!

library(lubridate)
month.abb[month(start):month(finish)]

如果这不起作用,请告诉我。

【讨论】:

    【解决方案2】:

    @Kim 的解决方案的问题是,如果间隔超过 1 年,它将不再起作用:

    library(lubridate)
    # works:
    month.abb[month("2016-09-24"):month("2016-11-02")]
    [1] "Sep" "Oct" "Nov"
    # wrong (should be Sep, Oct, Nov, Dec, Jan):
    month.abb[month("2016-09-24"):month("2017-01-02")]
    [1] "Sep" "Aug" "Jul" "Jun" "May" "Apr" "Mar" "Feb" "Jan"
    

    一种解决方案可能是:

    # correct:
    month.abb[unique(month(seq.Date(from = as.Date("2016-09-24"), to = as.Date("2017-01-02"), by = "day")))]
    [1] "Sep" "Oct" "Nov" "Dec" "Jan"
    

    【讨论】:

    • 很好,您表明公认的解决方案并不可靠。为了速度,您可以通过例如更改by = "day" by="25 days"。您不会错过一个独特的月份
    【解决方案3】:

    更进一步的可能包括年份:

    library(lubridate)
    
    # the next 12 months starting on the first of next month
    my_interval = interval(ceiling_date(Sys.Date(),unit = "month"),
    ceiling_date(Sys.Date(),unit = "month") + years(1) - days(1))
    
    year_month_vec <- paste0(year(seq.Date(from = date(int_start(my_interval)),to = date(int_end(my_interval)),by = "month")),"-",
      month.abb[month(seq.Date(from = date(int_start(my_interval)),to = date(int_end(my_interval)),by = "month"))])
    

    【讨论】:

      猜你喜欢
      • 2012-02-04
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多