代码之家  ›  专栏  ›  技术社区  ›  Alexander

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

  •  2
  • Alexander  · 技术社区  · 8 年前

    使用下面的示例数据,我试图基于三列变量(type、adict和sex)的值创建一个新变量“category”。

    但我想合并 type addict 分成一组 sex 在另一组。 所以我用 any 要从逻辑上得到一组逻辑向量,至少要有一个值为真,或者两个值都为真。

    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
    

    THX提前

    用户定义函数的更新 category

    还有一件事,如果我想在不使用case的情况下编写用户定义的函数,我可能会使用

    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 回复  |  直到 8 年前
        1
  •  1
  •   akrun    8 年前

    在OP的输入数据集中,所有列都是 factor 同时 NA s是字符串 "NA" 是的。同时,操作代码检查整个列 any 它返回一个 TRUE/FALSE 并回收不是预期的产出如果我们把它们改成 character 类和到 不适用 s(使用 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,而 %百分比 返回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)