r-将ifelse()与dplyr::if_any()一起使用,FALSE情况下的值返回NA



我正在尝试基于数据帧中的其他列创建一个标志列。

示例:

df <- tribble(
~x1, ~x2, ~x3, ~x4,
1, 0, 1, 1,
0, 0, NA, NA,
1, 0, NA, 1,
0, 0, NA, NA,
0, 1, NA, 0
)

我想创建一个标志列,这样,如果值1出现在x1~x4的任何一列中,那么标志的值将为1,否则为0。

res <- df |> mutate(flag = ifelse(if_any(x1:x4, function(x) x == 1), 1, 0))

我尝试过将dplyr::if_any()ifelse()一起使用,它似乎在大多数情况下都有效,但由于某种原因,在错误的情况下它会返回NA

> res
# A tibble: 5 × 5
x1    x2    x3    x4  flag
<dbl> <dbl> <dbl> <dbl> <dbl>
1     1     0     1     1     1
2     0     0    NA    NA    NA
3     1     0    NA     1     1
4     0     0    NA    NA    NA
5     0     1    NA     0     1

为什么会发生这种情况?有什么更好的解决方案?

edit:我试着看看if_any()函数本身返回了什么,它似乎返回了NA而不是false。

> res
# A tibble: 5 × 6
x1    x2    x3    x4  flag true_flase
<dbl> <dbl> <dbl> <dbl> <dbl> <lgl>     
1     1     0     1     1     1 TRUE      
2     0     0    NA    NA    NA NA        
3     1     0    NA     1     1 TRUE      
4     0     0    NA    NA    NA NA        
5     0     1    NA     0     1 TRUE      

perhttps://stackoverflow.com/a/44411169/10276092

您可以在%中使用%而不是==来忽略NA。

df %>%  mutate(flag = ifelse(if_any(.cols=x1:x4, .fns= ~ . %in% 1), 1, 0))

这里有一种方法:

library(dplyr)
library(tidyr)
df %>% 
rowwise %>%
mutate(flag = any(cur_data() == 1),
flag = replace_na(flag, 0))
x1    x2    x3    x4 flag 
<dbl> <dbl> <dbl> <dbl> <lgl>
1     1     0     1     1 TRUE 
2     0     0    NA    NA FALSE
3     1     0    NA     1 TRUE 
4     0     0    NA    NA FALSE
5     0     1    NA     0 TRUE 

或者将NA更改为0

df %>% mutate_each(funs(replace(., which(is.na(.)), 0))) %>% mutate(flag = ifelse(if_any(x1:x4, function(x) x == 1), 1, 0))

输出:

x1    x2    x3    x4  flag
<dbl> <dbl> <dbl> <dbl> <dbl>
1     1     0     1     1     1
2     0     0     0     0     0
3     1     0     0     1     1
4     0     0     0     0     0
5     0     1     0     0     1

使用rowSums的另一个选项

df %>% mutate(flag = +(rowSums(., na.rm = TRUE) > 0))
#----
# A tibble: 5 x 5
x1    x2    x3    x4  flag
<dbl> <dbl> <dbl> <dbl> <int>
1     1     0     1     1     1
2     0     0    NA    NA     0
3     1     0    NA     1     1
4     0     0    NA    NA     0
5     0     1    NA     0     1

从R手册页面

注意:

不要使用'==='和'!='对于测试,例如在"if"表达式中,其中必须获得单个"TRUE"或"FALSE"。除非你绝对确定不会发生任何异常,您应该使用"完全相同"函数。

遵循的建议

library(dplyr)
df %>% 
rowwise() %>% 
mutate(flag = if_any(starts_with("x"), ~ identical(.x, 1)) * 1 )
# A tibble: 5 × 5
# Rowwise: 
x1    x2    x3    x4  flag
<dbl> <dbl> <dbl> <dbl> <dbl>
1     1     0     1     1     1
2     0     0    NA    NA     0
3     1     0    NA     1     1
4     0     0    NA    NA     0
5     0     1    NA     0     1

相关内容

  • 没有找到相关文章

最新更新