代码之家  ›  专栏  ›  技术社区  ›  cephalopod

dplyr::if_else-检查条件并插入NA作为评估的一部分

  •  0
  • cephalopod  · 技术社区  · 6 年前

    我想解决一个简单的问题。我检查一个特定的条件,如果是真的,我插入一个 date 值或插入 NA (即留下一个空白单元格)。

    为了让它工作,我用 if_else 但它顽固地拒绝工作(我花了几个小时阅读SO和帮助页面)。

    这是我尝试过却失败了的:

    library(tidyverse)
    library(lubridate)
    
    df <- data.frame(date   = dmy(c("01/01/2019", "02/01/2019", "03/01/2019")),
               status = c("Active", "Suspended", "Active"),
               stringsAsFactors = FALSE)
    
      df %>%  mutate(sus_date = if_else(status == "suspended", 1, 2))   # This works
    
      df %>% mutate(sus_date = if_else(status == "suspended", date, NA)) # Throws an Error
      Error: `false` must be a `Date` object, not a logical vector
      Call `rlang::last_error()` to see a backtrace.
    
    
      df %>% mutate(sus_date = if_else(status == "suspended", date, NA_real_)) # Throws an error
      Error in as.Date.numeric(value) : 'origin' must be supplied
    

    这似乎是一个微不足道的问题,不应该花这么长时间才找到答案!

    有什么办法吗?

    另外,我想避免使用 base::ifelse 因为它改变了日期格式

    2 回复  |  直到 6 年前
        1
  •  4
  •   Onyambu    6 年前

    你可以强迫 NA 也开始约会了

    df %>% mutate(sus_date = if_else(status == "Suspended", date, ymd(NA))) 
            date    status   sus_date
    1 2019-01-01    Active       <NA>
    2 2019-01-02 Suspended 2019-01-02
    3 2019-01-03    Active       <NA>
    
        2
  •  1
  •   Ronak Shah    6 年前

    if_else 两者都需要 true false 如果是同一类型,则返回一个错误,因为

    class(NA)
    #[1] "logical"
    

    鉴于

    class(df$date)
    #[1] "Date"
    

    不幸的是,尽管我们 NA_real , NA_character_ 等等,但是没有 NA 所以你应该做的是

    library(dplyr)
    df %>% mutate(sus_date = as.Date(ifelse(status == "Suspended", date, NA)))
    
    #        date    status   sus_date
    #1 2019-01-01    Active       <NA>
    #2 2019-01-02 Suspended 2019-01-02
    #3 2019-01-03    Active       <NA>
    

    或者你已经在用R基了 ifelse

    transform(df, sus_date = as.Date(ifelse(status == "Suspended", date, NA)))
    
    推荐文章