Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ifelse on factor in R

I am restructuring a dataset of species names. It has a column with latin names and column with trivial names when those are available. I would like to make a 3rd column which gives the trivial name when available, otherwise the latin name. Both trivial names and latin names are in factor-class. I have tried with an if-loop:

  if(art2$trivname==""){  
    art2$artname=trivname   
    }else{  
      art2$artname=latname  
    }  

It gives me the correct trivnames, but only gives NA when supplying latin names.
And when I use ifelse I only get numbers.

As always, all help appreciated :)

like image 635
ego_ Avatar asked Jun 30 '12 15:06

ego_


People also ask

How does Ifelse function work in R?

R ifelse() Function Most of the functions in R take a vector as input and return a vectorized output. Similarly, the vector equivalent of the traditional if...else block is the ifelse() function. The output vector has the element x if the output of the test_expression is TRUE .

How do you write multiple conditions in an if statement in R?

Multiple Conditions To join two or more conditions into a single if statement, use logical operators viz. && (and), || (or) and ! (not). && (and) expression is True, if all the conditions are true.

Can Ifelse be nested in R?

The if-else statements can be nested together to form a group of statements and evaluate expressions based on the conditions one by one, beginning from the outer condition to the inner one by one respectively.


2 Answers

Getting only numbers suggests that you just need to add as.character to your assignments, and the if-else would probably work you also seem to not be referring to the data frame in the assignment?

if(as.character(art2$trivname)==""){  
    art2$artname=as.character(art2$trivname)
    }else{  
      art2$artname=as.character(art2$latname)
    }  

Option 2: Using ifelse:

 art2$artname= ifelse(as.character(art2$trivname) == "", as.character(art2$latname),as.character(art2$trivname))

It is probably easier (and more "R-thonic" because it avoids the loop) just to assign artname to trivial across the board, then overwrite the blank ones with latname...

art2 = art
art2$artname = as.character(art$trivname)
changeme = which(art2$artname=="")
art2$artname[changeme] = as.character(art$latname[changeme])
like image 41
beroe Avatar answered Sep 22 '22 15:09

beroe


Example:

art <- data.frame(trivname = c("cat", "", "deer"), latname = c("cattus", "canis", "cervus"))
art$artname <- with(art, ifelse(trivname == "", as.character(latname), as.character(trivname)))
print(art)
#   trivname latname artname
# 1      cat  cattus     cat
# 2            canis   canis
# 3     deer  cervus    deer

(I think options(stringsAsFactors = FALSE) as default would be easier for most people, but there you go...)

like image 193
Allan Engelhardt Avatar answered Sep 22 '22 15:09

Allan Engelhardt