R - create new column in data frame based on conditional

Viewed 5342

I need to create a column in a data frame with a string of yrs that will identify each yr as "leap" or "reg" (regular) automatically.

This is what I have thus far:

Delimit the time period

year<-(2009:2017)

Create a data frame with a single column for that time period

prd_df<-data.frame(year)

Create an empty column where "leap" and "reg" yrs will be identified

prd_df["leap"]<-NA

Base identification with a conditional loop

for(i in 1:length(prd_df$year)){
  if((prd_df$year[i]%%4==0)&(prd_df$year[i]%%100!=0)){
    prd_df$leap<-'leap'
  }else if((prd_df$year[i]%%4==0)&(prd_df$year[i]%%100==0)&(prd_df$year[i]%%400==0)){
    prd_df$leap<-'leap' 
  }else{
    prd_df$leap<-'reg'
  }
}

Create a table from the resulting data frame.

write.table(prd_df,
          file = "prd.csv",
          row.names = F, col.names = T,
          sep = "\t")

This is what I get:

"year"  "leap"
2009    "reg"
2010    "reg"
2011    "reg"
2012    "reg"
2013    "reg"
2014    "reg"
2015    "reg"
2016    "reg"
2017    "reg"

In the example above, 2012 and 2016 should be identified as "leap" in the second column, but it is not working. The conditional has worked fine before as part of other codes but I can't get it to work now. May it not be recognized prd_df$year as numeric?

Any suggestions will be most appreciated.

Thanks

4 Answers

We can use an ifelse

prd_df$leap <- with(prd_df, ifelse(year %%4== 0 & year %%100 !=0, "leap", "reg"))
prd_df$leap
#[1] "reg"  "reg"  "reg"  "leap" "reg"  "reg"  "reg"  "leap" "reg" 

Or with case_when from dplyr

library(dplyr)
prd_df %>%
       mutate(leap = case_when(year %%4 == 0 & year %% 100 !=0 ~ "leap", 
                               TRUE ~"reg"))
#   year leap
#1 2009  reg
#2 2010  reg
#3 2011  reg
#4 2012 leap
#5 2013  reg
#6 2014  reg
#7 2015  reg
#8 2016 leap
#9 2017  reg

For your code , You missed a [i], when assign the new value to column leaf

 year<-(2009:2017)
    prd_df<-data.frame(year)
    prd_df["leap"]<-NA

    for(i in 1:length(prd_df$year)){
        if((prd_df$year[i]%%4==0)&(prd_df$year[i]%%100!=0)){
            prd_df$leap[i]<-'leap'#add [i] here
        }
        else if((prd_df$year[i]%%4==0)&(prd_df$year[i]%%100==0)&(prd_df$year[i]%%400==0)){
            prd_df$leap[i]<-'leap' #add [i] here
        }else{
            prd_df$leap[i]<-'reg'#add [i] here
        }
    }


prd_df
  year leap
1 2009  reg
2 2010  reg
3 2011  reg
4 2012 leap
5 2013  reg
6 2014  reg
7 2015  reg
8 2016 leap
9 2017  reg

ifelse multiple conditions

with(prd_df, ifelse(year %%4== 0 & year %%100 !=0, "leap", ifelse(year %%4== 0 & year %%100 !=0&year%%400==0,"leap","reg")))
[1] "reg"  "reg"  "reg"  "leap" "reg"  "reg"  "reg"  "leap" "reg" 

Try to search lubridate package - I think there should be function to check if year is leap. And for conditions use mutate with case_when from dplyr package.

Whole code should be no longer than 5 lines :)

library(dplyr)
library(lubridate)

year_df <- data_frame(year = 1999:2017)

year_df <- year_df %>%
    mutate(leap = ifelse(leap_year(.$year), "leap", "reg"))
Related