【问题标题】:Remove all dates in a range over multiple years删除多年范围内的所有日期
【发布时间】:2020-10-21 12:02:55
【问题描述】:

问题:

我有一个多年数据集,我想在其中删除所有年份的一系列日期(例如 5 月 1 日至 8 月 31 日)。我想在所有年份中保留从 4 月 30 日到 9 月 1 日的日期。

数据示例:

dat <- data.frame(
  "Date" = c("2000-08-01","2000-11-02","2001-08-03","2001-11-04","2002-06-05","2002-02-06","2000-08-07","2000-02-08","2001-06-09","2001-11-10"),
  "Type" = c("A", "B", "C", "B", "C", "B", "A", "A", "C", "B"),
  "Num" = c(8,6,5,6.5,5,5.5,6,7,4,3)
)
dat

我的尝试:

我创建了一个对象,其中包含所有年份的 5 月 1 日的日期,并使用 for 循环删除之后的天数,直到 8 月 31 日。我知道这是一种非常迂回的方式,所以我想知道是否有一个更简单的解决方案,因为这是一个相当大的数据集。

dates_start <- as.Date(c("2000-05-01", "2001-05-01", "2002-05-01"))

for(i in 1:length(dates_start)){
  dat <- dat[!(as.Date(dat$Date) >= (dates_start[i] + 123)),]
}

编辑:

我计划多次运行此过滤/删除以获取不同的数据集,并且在某些情况下,我想删除月中的日期(例如 4 月 15 日至 8 月 16 日),因此仅删除某些月份不会在这里工作。

【问题讨论】:

    标签: r date dplyr


    【解决方案1】:

    您可以动态创建日期以删除:

    library(dplyr)
    library(lubridate)
    
    start <- '04-15'
    end <- '08-16'
    
    dat %>% 
      mutate(Date = as.Date(Date), 
             year = year(Date)) %>%
      filter(!(Date >= ymd(paste(year, start, sep = '-')) & 
              Date <= ymd(paste(year, end, sep = '-'))))
    
    
    #       Date Type Num year
    #1 2000-11-02    B 6.0 2000
    #2 2001-11-04    B 6.5 2001
    #3 2002-02-06    B 5.5 2002
    #4 2000-02-08    A 7.0 2000
    #5 2001-11-10    B 3.0 2001
    

    【讨论】:

    • 我应该更清楚。我计划多次执行此过滤/删除,并且在某些情况下,我想删除月中的日期(例如 4 月 15 日至 8 月 16 日),因此此方法不起作用。
    【解决方案2】:

    这行得通吗:

    > library(dplyr)
    > library(lubridate)
    > dat$Date <- ymd(dat$Date)
    > dat %>% filter(!month(Date) %in% 5:8)
            Date Type Num
    1 2000-11-02    B 6.0
    2 2001-11-04    B 6.5
    3 2002-02-06    B 5.5
    4 2000-02-08    A 7.0
    5 2001-11-10    B 3.0
    > 
    

    【讨论】:

    • 我应该更清楚。我计划多次执行此过滤/删除,并且在某些情况下,我想删除月中的日期(例如 4 月 15 日至 8 月 16 日),因此此方法不起作用。
    【解决方案3】:

    由于您的日期是 character,您可以使用 sub 提取月份,然后使用该月份编号作为子集。

    x <- as.integer(sub("\\d+-(\\d+)-\\d+", "\\1", dat$Date))
    #x <- as.integer(format(as.Date(dat$Date), "%m")) #Alternative using Date
    dat[x<5L | x>8L,]
    #         Date Type Num
    #2  2000-11-02    B 6.0
    #4  2001-11-04    B 6.5
    #6  2002-02-06    B 5.5
    #8  2000-02-08    A 7.0
    #10 2001-11-10    B 3.0
    

    对于还有天数的范围 - 天数低于 10 需要有一个前导 0

    x <- as.integer(sub("\\d+-(\\d+)-(\\d+)", "\\1\\2", dat$Date))
    dat[x<501L | x>831L,]
    

    或将年份粘贴到月份 - 这可能会导致 2 月 29 日出现问题:

    x <- format(as.Date(dat$Date), "%Y")
    dat[as.Date(dat$Date) < as.Date(paste0(x,"-05-01")) |
        as.Date(dat$Date) > as.Date(paste0(x,"-08-31")),]
    

    或者:

    x <- as.Date(paste0("2000-", format(as.Date(dat$Date), "%m-%d")))
    dat[x<as.Date("2000-05-01") | x>as.Date("2000-08-31"),]
    

    【讨论】:

    • 我应该更清楚。我计划多次执行此过滤/删除,并且在某些情况下,我想删除月中的日期(例如 4 月 15 日至 8 月 16 日),因此此方法不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多