具有多个列和条件的if语句

时间:2018-07-23 06:35:44

标签: r if-statement dplyr

利用以下示例数据,我试图基于三列变量(类型,上瘾者和性别)的值创建一个新的变量“类别”。

但是我想将typeaddict合并为一个组,将sex合并为另一组。 因此,我使用any从逻辑上获取一组逻辑向量,是至少一个值为true还是两个均为true。

df <- data.frame(type = c(NA, "bad",NA), addict=c('visky','wine',NA),
                 sex=c(NA,'male',NA))


> df
  type addict  sex
1 <NA>  visky <NA>
2  bad   wine male
3 <NA>   <NA> <NA>

library(dplyr)


df%>%
  mutate(category=ifelse(any(is.na(type)&addict=="visky")&any(is.na(sex)),"categ1",
         ifelse(any(type=="bad"|addict=="wine")&any(!is.na(sex)),"categ2",
         ifelse(any(is.na(type)&is.na(addict))&any(is.na(sex)),"categ3",NA))))


       type addict  sex category
1 <NA>  visky <NA>   categ1
2  bad   wine male   categ1
3 <NA>   <NA> <NA>   categ1

可以看出我的ifelse循环无法正常工作。我不知道为什么吗?

预期输出

       type addict  sex category
1 <NA>  visky <NA>   categ1
2  bad   wine male   categ2
3 <NA>   <NA> <NA>   categ3

提前谢谢

用户定义的功能category

的更新

还有一件事,如果我想编写用户定义的函数而不使用case_when进行相同的操作,我可能会使用

categ <- function(type,addict,sex){ 

if (any(is.na(type)&addict=="visky"&is.na(sex))){ 
"categ1" 
} 
else{ 
NA 
} 

}

但这也给

df%>%
mutate(category=categ(type,addict,sex))

  type addict  sex category
1 <NA>  visky <NA>   categ1
2  bad   wine male   categ1
3 <NA>   <NA> <NA>   categ1

1 个答案:

答案 0 :(得分:1)

在OP的输入数据集中,所有列均为factor,并且所有NA均为字符串"NA"。另外,OP的代码正在使用any检查整个列,该列返回单个TRUE/FALSE并被回收,这不是预期的输出。如果我们将它们更改为character类和NA(使用case_when

df %>% 
  mutate(category = case_when(
            is.na(type) & addict %in% "visky" & is.na(sex) ~ "categ1",
            type %in% c("bad", "wine") & !is.na(sex) ~ "categ2", 
            is.na(type) & is.na(addict) & is.na(sex) ~ "categ3", 
            TRUE ~ NA_character_))
#   type addict  sex category
#1 <NA>  visky <NA>   categ1
#2  bad   wine male   categ2
#3 <NA>   <NA> <NA>   categ3

注意:这里,我们使用%in%代替==,因为==返回NA元素的NA,而%in%返回FALSE。但是,我们仍然可以将==is.na

结合使用

基于OP的注释,我们可以创建一个自定义函数(不同的函数)

categFn <- function(typeCol, addictCol, sexCol) {

           if(any(is.na(typeCol) & addictCol== "visky") & any(is.na(sexCol))) {
               "categ1"
              } else NA
            }

df %>% 
     mutate(categ = categFn(type, addict, sex))

数据

df <- data.frame(type = c(NA, "bad",NA), addict=c('visky','wine',NA),
                  sex=c(NA,'male',NA), stringsAsFactors = FALSE)