Search code examples
rif-statementcaseroundingmutate

How would one round up to the nearest whole value only IF the value meets criteria, and keeping the original column within the df


How would one round up to the nearest whole value only IF the values after decimal is >= 0.75? And keeping the original column within the df.

df1 <- data.frame(names = c("A","B","C","D","E"),
                  years_in_rank = c(3.15, 4.25, 5.75, 6.90, NA))

# Desired Outcome

names  years_in_rank   final_yir
A      3.15            3.15
B      4.25            4.25
C      5.75            6.00
D      6.90            7.00
E      NA              NA

**This was the very long approach, that prompted the question. ** (Im going to guess some beautiful use of case when can be used instead.)

library(tidyr)
# Transforming years in rank to separate columns
df1 %>%  separate(years_in_rank, into = c("years_whole", "years_deci"),
remove = FALSE)

#Transform years_in_deci back to decimal
df1$years_deci <- as.numeric(as.character(df1$years_deci))/100

# Rounding rules
df1 <- df1 %>% 
  mutate(years_deci_rounded = if_else(years_deci >= 0.75, round(years_deci, 0), years_deci),.after = years_deci)

#Final desired output column
df1 <- df1 %>% 
  mutate(final_yir = if_else(years_deci_rounded == 1, as.numeric(years_whole) + years_deci_rounded, years_in_rank),.after = years_deci_rounded)

Solution

  • One approach using floor

    cbind(df1, final_yir = 
      ifelse(df1$years_in_rank - floor(df1$years_in_rank) >= 0.75, 
             ceiling(df1$years_in_rank), df1$years_in_rank))
      names years_in_rank final_yir
    1     A          3.15      3.15
    2     B          4.25      4.25
    3     C          5.75      6.00
    4     D          6.90      7.00
    5     E            NA        NA
    

    With

    library(dplyr)
    
    df1 %>% 
      mutate(final_yir = ifelse(years_in_rank - floor(years_in_rank) >= 0.75, 
                                ceiling(years_in_rank), years_in_rank))
      names years_in_rank final_yir
    1     A          3.15      3.15
    2     B          4.25      4.25
    3     C          5.75      6.00
    4     D          6.90      7.00
    5     E            NA        NA