简体   繁体   中英

R function with variable number of arguments for ifelse

I have a script that creates a column so that I know which rule should be applied to each row in a dataframe.

EndoSubset$FU_Group<-ifelse(EndoSubset$IMorNoIM=="No_IM","Rule1",
                            ifelse(EndoSubset$IMorNoIM=="IM","Rule2",
                             ifelse(EndoSubset$IMorNoIM=="AnotherIM","Rule3",
                           "NoRules")))

I want to make this into a function so that there can be any number of rules and any number of conditions for a column so it could be:

  EndoSubset$FU_Group<-ifelse(EndoSubset$IMorNoIM=="No_IM","Rule1",
                                ifelse(EndoSubset$IMorNoIM=="IM","Rule2",
                                ifelse(EndoSubset$IMorNoIM=="AnotherIM","Rule3",
                                ifelse(EndoSubset$IMorNoIM=="SomeOtherIM","Rule4",
                                ifelse(EndoSubset$IMorNoIM=="LotsOfIM","Rule5",
                               "NoRules")))

I understand that I can use the ellipsis for this but I don't understand how to use this for both the conditional string ("No_IM, "IM,"AnotherIM", etc) and the Rule string at the same time ("Rule1","Rule2","Rule3" etc.)

This answer is based upon another, incomplete answer that has been deleted.

You can use case_when() from the dplyr package to achieve this. It takes an arbitrary number of conditions. Since you don't give a reproducible example, I show how this works with mtcars :

library(dplyr)
mtcars$cyl_group <- case_when(mtcars$cyl == 4 ~ "Rule1",
                              mtcars$cyl == 6 ~ "Rule2",
                              TRUE ~ "NoRules")
mtcars[2:5, ]
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb cyl_group
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4     Rule2
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1     Rule1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1     Rule2
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2   NoRules

As you can see, you can easily connect a condition with a value using ~ . Your two examples can probably be solved like this (I cannot check this, since you don't give your data):

EndoSubset$FU_Group <- case_when(EndoSubset$IMorNoIM == "No_IM" ~ "Rule1",
                                 EndoSubset$IMorNoIM == "IM" ~ "Rule2",
                                 EndoSubset$IMorNoIM == "AnotherIM" ~ "Rule3",
                                 TRUE ~ "NoRules")

EndoSubset$FU_Group <- case_when(EndoSubset$IMorNoIM == "No_IM" ~ "Rule1",
                                 EndoSubset$IMorNoIM == "IM" ~ "Rule2",
                                 EndoSubset$IMorNoIM == "AnotherIM" ~ "Rule3",
                                 EndoSubset$IMorNoIM == "SomeOtherIM" ~ "Rule4",
                                 EndoSubset$IMorNoIM == "LotsOfIM" ~ "Rule5",
                                 TRUE ~ "NoRules")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM