'case_when()' 在 !=

`case_when()` passes NA through when !=

提问人:maia-sh 提问时间:8/7/2020 更新时间:8/11/2020 访问量:2361

问:

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

下面的 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

创建于 2020-08-06 由 reprex 软件包 (v0.3.0)

R dplyr na equality

评论

1赞 akrun 8/7/2020
只要有 NA,您就可以将其用作返回值 NAis.na==

答:

2赞 akrun 8/7/2020 #1

问题出在 和 上。与 NA 相比的任何值都返回 。也可以在比较中纠正它,但随后需要重复。或者,一个简单的解决方法是将 更改为不同的值,进行比较并与原始数据集绑定==NANAis.naNA

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, .)

评论

1赞 maia-sh 8/11/2020
谢谢,阿克伦!正如你所说,我也做了一些事情。我也会发布它,以防它对其他人有用。is.na
1赞 maia-sh 8/11/2020 #2

就像@akrun提到的,使用“exclusive or”/有一种解决方法。这是我最终使用的内容:is.naxor

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_
  ))