【问题标题】:mutate to NA based on condition根据条件变异为 NA
【发布时间】:2021-01-02 21:16:32
【问题描述】:

我有一个数据框,其中包含两个日期列(date_a 和 date_b)和一个因子列 (c) df

现在我想用 NA 替换 date_a 中的所有值,如果 date_b 不是 NA(或者如果 c 不是 NA)。我已经尝试了过去几个小时,我得到的最接近的是这段代码:

df<- df %>% 
  mutate(date_a = case_when(
    is.na(c) == FALSE ~ NA
  ))

但这会将整个 date_a 列替换为 NA。

希望有人能帮帮我。

谢谢!

【问题讨论】:

  • 您不应将数据添加为图像。我们无法从图像中复制数据。以更易于复制的可复制格式添加它们。阅读how to give a reproducible example

标签: r date na dplyr


【解决方案1】:

这是带有is.na&lt;- 的基本 R 单线。
测试数据集为Ian Campbell's answer中的数据集。

is.na(df$date_a) <- with(df, !(is.na(date_b) | is.na(c)))

df
#      date_a     date_b     c
#1 2012-10-11       <NA>  <NA>
#2       <NA> 2016-01-08 house
#3 2019-12-19       <NA>  <NA>
#4 2019-06-14       <NA>  <NA>
#5 2014-04-22       <NA>  <NA>
#6       <NA> 2017-08-03  boat
#7 2018-11-20       <NA>  <NA>
#8       <NA> 2017-06-16  boat
#9       <NA> 2016-03-17  boat

【讨论】:

    【解决方案2】:

    您可以使用ifelse 来定义条件值。

    ifelse 的第一个参数是条件。在这种情况下,我们希望!is.na(date_b)|!is.na(c) 指示其中一个是否不是NA。如果第一个参数的计算结果为TRUE,那么第二个参数就是我们想要的。在这种情况下,可以只返回 date_a 的值。如果参数 1 的计算结果为 FALSE,那么最后一个参数就是我们想要的,我们需要使用 NA_character,因为该列的其余部分是字符。

    library(dplyr)
    df %>% 
      mutate(date_a = ifelse(!is.na(date_b)|!is.na(c),NA_character_,date_a))
          date_a     date_b     c
    1 2012-10-11       <NA>  <NA>
    2       <NA> 2016-01-08 house
    3 2019-12-19       <NA>  <NA>
    4 2019-06-14       <NA>  <NA>
    5 2014-04-22       <NA>  <NA>
    6       <NA> 2017-08-03  boat
    7 2018-11-20       <NA>  <NA>
    8       <NA> 2017-06-16  boat
    9       <NA> 2016-03-17  boat
    

    case_when也可以这样做,但只有一个条件时就不需要了:

    df %>% 
       mutate(date_a = case_when(!is.na(date_b)|!is.na(c) ~ NA_character_,
              TRUE ~ date_a))
    

    如果您的列属于不同的类别(正如 @akrun 在 cmets 中指出的那样),例如 Date,您可以尝试以下操作:

    df %>% 
       mutate(date_a = case_when(!is.na(date_b)|!is.na(c) ~ as.Date(NA), TRUE ~ date_a))
    

    样本数据:

    df <- structure(list(date_a = c("2012-10-11", "2016-01-08", "2019-12-19", 
    "2019-06-14", "2014-04-22", "2017-08-03", "2018-11-20", "2017-06-16", 
    "2016-03-17"), date_b = c(NA, "2016-01-08", NA, NA, NA, "2017-08-03", 
    NA, "2017-06-16", "2016-03-17"), c = c(NA, "house", NA, NA, NA, 
    "boat", NA, "boat", "boat")), class = "data.frame", row.names = c(NA, 
    -9L))
    

    【讨论】:

    • @akrun 好点,屏幕截图中是否有提示类型为日期?
    • 谢谢各位,日期列确实属于 Date 类。所以我尝试了第三个选项,它工作得很好。谢谢大家!
    【解决方案3】:

    您还必须添加其他条件:

    df %>% 
      mutate(date_a = case_when(
        is.na(c) ~ NA_character_,
        TRUE     ~ c
      ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-13
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多