steppermotor
steppermotor

Reputation: 701

Alternative to if statement in R

I use a series of if statements to check if Year is equal to a certain value, and then calculate a statement. Is there a more efficient and faster way to perform the following instead of using if statements?

for (i in 1:length(O$Year))
{
   if (Year[i] == "2012") {
      O$SD[i] = C[i]/5408666
   } else if ( Year[i] == "2013") {
      O $SD[i] = C[i]/5300759
   } else if ( Year[i] == "2014") {
      O$SD[i] = C[i]/5410924
   } else if ( Year[i] == "2015") {
      O$SD[i] = C[i]/5446029
   } else if ( Year[i] == "2016") {
      O$SD[i] = C[i]/5480869
   } else 
      O$SD[i] = C[i]
}

**Data set named O** 
   **SD Year C**
     43 2012 4
     23 2012 5
     12 2014 3
     53 2014 3

Upvotes: 1

Views: 2575

Answers (4)

Benjamin
Benjamin

Reputation: 17369

I think you'll be most efficient if you use match to assign your denominator to each row.

match_year_row <- match(O$year, 2012:2016)

O$denominator <- c(5408666,5300759,5410924,5446029,5480869)[match_year_row]
O$denominator[is.na(O$denominator)] <- 1
O$SD <- with(O, C / denominator)

Upvotes: 0

Janna Maas
Janna Maas

Reputation: 1134

you can use dplyr::recode, switch works similarly:

dummy data:

library(dplyr)

O <- read.table(text="SD Year C
  43 2012 4
23 2012 5
12 2014 3
53 2014 3", header=TRUE, stringsAsFactors=FALSE)

recode: note the backticks `` around the values to be replaced:

O %>% mutate(SD= recode(Year,`2012`=C/540866,
                             `2014`=C/5410924))

result:

            SD Year C
1 7.395547e-06 2012 4
2 9.244434e-06 2012 5
3 5.544340e-07 2014 3
4 5.544340e-07 2014 3

Upvotes: 1

BLT
BLT

Reputation: 2532

I'd love to see how to do this with switch(), and I would typically use dplyr piping to avoid having to type the name of the data.frame so often, but here's what I would do here:

O$SD <- ifelse(O$Year == '2012', O$C/5408666,
               ifelse(O$Year == '2013', O$C/5300759,
                      ifelse(O$Year == '2014', O$C/5410924,
                             ifelse(O$Year == '2015', O$C/5446029,
                                    ifelse(O$YEar == '2016', O$C/5480869, O$C))))

It doesn't save a ton of typing, but it does save a for loop.

Upvotes: 0

kostr
kostr

Reputation: 856

How about this?

tmp <- data.frame(year = c("2012","2013","2014","2015","2016"), 
denominator = c(5408666,5300759,5410924,5446029,5480869))

for(i in 1:nrow(O)){
O[i,4] <- O$C[i]/tmp[which(as.character(tmp$year)==O$Year[i]),2]
}

Upvotes: 1

Related Questions