Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test for multiple conditions in if else flow control in r

It seems to be a very simple flow control structure doubt, however I am having a hard time finding the correct syntax for this in R, I have tried numerous without success. I must be missing something really obvious.

I wanted to loop in a list with Brazilian states codes, and return the region it is in. My aim is to manipulate a larger data set, not a list, but here is a MWE using a list:

a <- c("RO", "AC", "AM" ,"RR", "PA", "AP", "TO", "MA", "PI", "CE", "RN", "PB", "PE", "AL", "SE", "BA", "MG", "ES", "RJ", "SP")

setregion <- function(uf) {
  pb = txtProgressBar(min = 0, max = length(uf), initial = 0) 
  region_out<-list()
  for (i in length(uf)) {
    if (uf %in% c("RO"  ,"AC" ,"AM" ,"RR", "PA" , "AP" , "TO")) {
      region_out <- append(region_out,"North")
    } else if (  uf %in% c("MA","PI","CE","RN","PB","PE","AL","SE","BA")) {
      region_out <-append(region_out,"Northeast")
    } else if ( uf %in% c("MG","ES","RJ","SP")){
      region_out <- append(region_out,"Southeast")
    } else if ( uf %in% c("PR", "SC", "RS")){
      region_out <- append(region_out,"South") 
    } else if ( uf %in% c("MS","MT","GO", "DF")){
      region_out <-append(region_out,"Midwest")
    }
    setTxtProgressBar(pb,i)
  }
  return(region_out)
}

setregion(a)

Upon running the above code, it seems the if loop breaks the for loop as well, and it only returns "North", which is the response to the very first item in the list.

I would expect a list with looking like:

"North", "North", "North" ,"North", "North", "North","North", "Northeast", "Northeast",...
  • What am I missing?
like image 344
lf_araujo Avatar asked Dec 17 '22 18:12

lf_araujo


1 Answers

The problem with normal if-else is that it is not vectorized. You need a vectorized approach, such as the ifelse function. But, in your case, since you have so many conditions, the case_when function from the dplyr library might make more sense:

library(dplyr)

setregion <- function(uf) {
    region_out <- case_when(
        uf %in% c("RO","AC","AM","RR","PA","AP","TO") ~ "North",
        uf %in% c("MA","PI","CE","RN","PB","PE","AL","SE","BA") ~ "Northeast",
        uf %in% c("MG","ES","RJ","SP") ~ "Southeast",
        uf %in% c("PR", "SC", "RS") ~ "South",
        uf %in% c("MS","MT","GO", "DF") ~ "Midwest"
    )
    return(region_out)
}
like image 125
Tim Biegeleisen Avatar answered May 26 '23 09:05

Tim Biegeleisen