【问题标题】:`case_when()` passes NA through when !=`case_when()` 当 != 时通过 NA
【发布时间】:2020-08-06 17:14:37
【问题描述】:

我正在尝试创建一个新列来指示两个现有列之间的差异。 NAs 应被视为值并应标记为“差异”。但是,NAs 正在“通过”!= 比较器。我一直在寻找 case_when 参数来处理 NAs 并寻找替代的不相等比较器无济于事。

下面的reprex显示了当前的输出和期望的输出。

提前感谢您的帮助!

library(dplyr)
library(tidyr)
library(tibble)

df <- 
  expand_grid(x = c("a", NA), y = c("b", NA)) %>% 
  add_row(x = "a", y = "a") %>% 
  add_row(x = "b", y = "b")

df
#> # A tibble: 6 x 2
#>   x     y    
#>   <chr> <chr>
#> 1 a     b    
#> 2 a     <NA> 
#> 3 <NA>  b    
#> 4 <NA>  <NA> 
#> 5 a     a    
#> 6 b     b

# Non-desired output: NA's passed through instead of treated as values
  df %>% 
  mutate(z = case_when(
    x == "a" & y == "a" ~ "a",
    x == "b" &  y == "b" ~ "b",
    x != y ~ "difference"
  ))
#> # A tibble: 6 x 3
#>   x     y     z         
#>   <chr> <chr> <chr>     
#> 1 a     b     difference
#> 2 a     <NA>  <NA>      
#> 3 <NA>  b     <NA>      
#> 4 <NA>  <NA>  <NA>      
#> 5 a     a     a         
#> 6 b     b     b

# Desired output
  df %>% 
  add_column(z = c(rep("difference", 3), NA_character_, "a", "b"))
#> # A tibble: 6 x 3
#>   x     y     z         
#>   <chr> <chr> <chr>     
#> 1 a     b     difference
#> 2 a     <NA>  difference
#> 3 <NA>  b     difference
#> 4 <NA>  <NA>  <NA>      
#> 5 a     a     a         
#> 6 b     b     b

reprex package (v0.3.0) 于 2020-08-06 创建

【问题讨论】:

  • 你可以使用is.na,因为==在有NA时返回NA

标签: r dplyr na equality


【解决方案1】:

问题在于==NA。与 NA 相比的任何值都会返回 NA。在比较中也可以使用is.na 进行更正,但需要重复。或者一个简单的解决方法是将NA 更改为不同的值,进行比较并与原始数据集绑定

library(dplyr)
df %>% 
   mutate(across(x:y, replace_na, '')) %>%
   transmute(z = case_when(
    x == "a" & y == "a" ~ "a",
    x == "b" &  y == "b" ~ "b",
    x != y ~ "difference"
    )) %>%
   bind_cols(df, .)

【讨论】:

  • 谢谢,阿克伦!正如你所指出的,我还用is.na 解决了一些问题。我也会发布它以防它对其他人有用。
【解决方案2】:

就像@akrun 提到的那样,is.na 有一个解决方法,它带有“独占或”/xor。这是我最终使用的:

df %>% 
  mutate(z = case_when(
    x == y ~ x,
    xor(is.na(x), is.na(y)) ~ "difference",
    x != y ~ "difference",
    is.na(x) & is.na(y) ~ NA_character_
  ))

【讨论】:

    猜你喜欢
    • 2022-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2019-10-20
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    相关资源
    最近更新 更多