首页 > 解决方案 > 使用嵌套的 ifesle 进行变异

问题描述

我确实得到了错误的结果,我做错了什么?

df <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA))
df <-mutate(df,result=ifelse(is.na(x),NA,ifelse(any(!is.na(y),!is.na(z)),1,0)))

我明白了(数据[2,4]==0)

   x  y  z result
1  1  1 NA      1
2  1 NA NA      1
3 NA NA NA     NA

而不是这个:

df_wanted <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA), result=c(1,0,NA))

   x  y  z result
1  1  1 NA      1
2  1 NA NA      0
3 NA NA NA     NA

标签: rdataframeif-statementdplyr

解决方案


我们可以使用|而不是any因为any返回单个 TRUE/FALSE 作为输出

with(df, any(!is.na(y), !is.na(z)))
#[1] TRUE

并且整个列都被回收了,因为第一个ifelse带有“x”的第三行已经返回“NA”,所有其他的都返回 1

相反,我们需要为每一行执行此操作,这可以通过|

library(dplyr)
df %>%
   mutate(result = ifelse(is.na(x), NA, ifelse(!is.na(y)|!is.na(z), 1, 0)))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA

或者另一种选择是case_when

df %>%
  mutate(result = case_when(is.na(x) ~ NA_integer_, 
                        !is.na(y)| !is.na(z) ~ 1L, 
                        TRUE ~ 0L))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA

或与coalesce

df %>%
   mutate(result = x * +coalesce(!is.na(y)|!is.na(z)))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA

推荐阅读