【问题标题】:How to add to a date with ifelse如何使用 ifelse 添加日期
【发布时间】:2020-05-01 05:13:24
【问题描述】:

我有一个数据框,其中包含一个日期列和一个名为 Rule 的文本列。 如果规则列中的文本是“Rule_1”,我想在该行的日期上添加 3 年,但如果“Rule_2”则为两年。

Date        Rule     NewDate
2010-01-01  Rule_1   2013-01-01
2012-01-01  Rule_2   2014-01-01
2015-01-01  No_Rule  2015-01-01

我似乎在使用lubridate 添加年份时遇到问题

 ifelse(df$Rule=="Rule1",df$Date %m+% years(3),df$Date)

它将添加的日期转换为我认为是从原点开始的天数(?1970)。 但是,如果我在没有 ifelse 的情况下运行表达式df$Date %m+% years(3),那么它可以正常工作。怎么办?

【问题讨论】:

  • 是否有任何答案解决了您的问题?如果是,请将答案标记为已接受,否则请发表评论

标签: r


【解决方案1】:

既然您已经在使用一个tidyverse 包(lubridate),那么来自dplyrcase_when 怎么样?这是一个矢量化的if - 如果您有多个条件,基本上可以让您避免一堆嵌套的ifelse 语句。

library(dplyr)
df %>% 
  mutate(NewDate_Demo = case_when(Rule == "Rule_1" ~ Date %m+% years(3),
                          Rule == "Rule_2" ~ Date %m+% years(2),
                          TRUE ~ Date))
# A tibble: 3 x 4
  Date       Rule    NewDate    NewDate_Demo
  <date>     <chr>   <date>     <date>      
1 2010-01-01 Rule_1  2013-01-01 2013-01-01  
2 2012-01-01 Rule_2  2014-01-01 2014-01-01  
3 2015-01-01 No_Rule 2015-01-01 2015-01-01  

dplyr 也提供if_else,它与base::ifelse 具有相同的通用语法,但不会与lubridate 中断。 https://github.com/tidyverse/lubridate/issues/644

【讨论】:

    【解决方案2】:

    基础 ifelse 函数类型不稳定。如果使用 dplyr 实现 if_else(),则可以使用。这会自动检查并保留所需的输出类型。 从其文档中:

    与基础 ifelse() 相比,这个函数更加严格。它检查 true 和 false 是否为同一类型。这种严格性使输出类型更可预测,并且速度更快。

    library(dplyr)
    library(lubridate)
    
    # never mix up tidyverse and data.table but damn, fread() is awesome :D 
    df <- data.table::fread("
    Date        Rule     NewDate
    2010-01-01  Rule_1   2013-01-01
    2012-01-01  Rule_2   2014-01-01
    2015-01-01  No_Rule  2015-01-01") %>% 
      as_tibble() %>% 
      mutate_at(.vars = c(1, 3), as_date)
    
    # more type stable ifelse
    dplyr::if_else(df$Rule=="Rule_1", df$Date %m+% years(3), df$Date)
    
    # desired output with nested if_else
    # faster than case_when()
    dplyr::if_else(df$Rule=="Rule_1", df$Date %m+% years(3), 
                   if_else(df$Rule=="Rule_2", df$Date %m+% years(2), df$Date))
    
    # piped dplyr way
    df %>% 
      mutate(desired_date = if_else(Rule == "Rule_1",
                                    true = Date %m+% years(3), 
                                    false = if_else(Rule == "Rule_2", 
                                                    true = Date %m+% years(2),
                                                    false = Date)))
    

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 2022-12-03
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 2021-08-01
      • 2010-10-08
      相关资源
      最近更新 更多