Why does IFELSE logic work differently on what appear to be the same values?

February 22, 2013
By

(This article was first published on Econometric Sense, and kindly contributed to R-bloggers)

Embarrassingly I’m stumped on this…

I have a program in R for looking at grade distributions in my class. I found something weird recently with my ‘ifelse’ processing. I noticed that my program seemed to be over counting Cs and under counting Bs.

I’m not sure what’s going on. It happened in the case where I was adding extra credit. It has something to do with the addition operation and variable assignment I guess. When I process untransformed data I get the correct # of Bs and Cs. But my goal in a program like this was flexibility – enter the data in excel and process. I’d prefer to add extra credit/curves/corrections etc. in R through processing vs. doing it all in excel.

A very short modified  version (w/out reading in the data from csv) follows. Am I actually making a simple error in my math, or does R see these values differently than they may appear? I’m admittedly not a normal user of the ‘ifelse’ logic in R.  But even if it is wrong it should give me the same wrong answer when applied against what appear to be the same values! If I run the summary function  against all the vars I get matching results for grades\$grade2 and grades\$ec (the modified grade)

`grades2 <- c(0.72,0.56,0.84,0.84,1.04,0.48,0.96,0.8,0.68,0.92,0.72,0.6,0.92,0.72,0.88,0.88,0.76,0.96,0.76,0.52,1,0.88,0.88,0.88,0.64) grades1 <-c(0.64,0.48,0.76,0.76,0.96,0.4,0.88,0.72,0.6,0.84,0.64,0.52,0.84,0.64,0.8,0.8,0.68,0.88,0.68,0.44,0.92,0.8,0.8,0.8,0.56) grades <- data.frame(cbind(grades1,grades2)) # format grades grades\$letter1 <- ifelse(grades\$grades1 >= .90,"A", ifelse(grades\$grades1 >= .80 & grades\$grades1 < .90, "B",ifelse (grades\$grades1 >= .70 & grades\$grades1 < .80,"C",ifelse(grades\$grades1 >= .60 & grades\$grades1 < .70, "D","F")))) # letter grade distributiontable(grades\$letter1)  grades\$letter2 <- ifelse(grades\$grades2 >= .90,"A", ifelse(grades\$grades2 >= .80 & grades\$grades2 < .90, "B",ifelse (grades\$grades2 >= .70 & grades\$grades2 < .80,"C",ifelse(grades\$grades2 >= .60 & grades\$grades2 < .70, "D","F")))) # letter grade distributiontable(grades\$letter2)  # bonus: grade1 to = grade2 grades\$ec <- grades1 + .08 # why is it that this misclassifies an .80 as a C in this case but not in the# case of all of the previous grade1 and grade2 instances?? grades\$letter.ec <- ifelse(grades\$ec >= .90,"A", ifelse(grades\$ec >= .80 & grades\$ec < .90, "B",ifelse (grades\$ec >= .70 & grades\$ec < .80,"C",ifelse(grades\$ec >= .60 & grades\$ec < .70, "D","F")))) # letter grade distributiontable(grades\$letter.ec)  summary(grades)  # if you print grades you can see that it missclassifies an .80 as a C# for obs 8 for the calculated ec grade, but correctly classifies# an .80 as  a B for cases of the grade1 and grade2 variables`

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...