Mrmoleje
Mrmoleje

Reputation: 493

Applying a function to round selected variables

I would like to develop a function with an if statement, so that when the function is run over a dataframe only certain variables are amended.

library(dplyr)

df1 <- tibble(
  geo_lev = c("USA", "France", "England", "Ukraine", "Poland"),
  reg_lev = c("one", "two", "one", "two", "one"),
  number = c(101, 10, 14, 19, 22))

This is how I would round the data without a function

df1 %>% 
  mutate(number=ifelse(geo_lev =='USA' & reg_lev !='two', 
                                    round(number, -1),
                       number))

I've tried to develop a function to do this but it doesn't quite work

round <- function(x) {
  result = round(x, -1) 
  if (geo_lev =='USA' & reg_lev !='two')}

One the function is applied I would like the data to look like this

round(df1)

df1 <- tibble(
  geo_lev = c("USA", "France", "England", "Ukraine", "Poland"),
  reg_lev = c("one", "two", "one", "two", "one"),
  number = c(100, 10, 14, 19, 22))

Does anyone know how I would develop the function? I'm new to writing functions so there's a syntax error that I can't figure out.

Upvotes: 1

Views: 51

Answers (2)

BetterCallMe
BetterCallMe

Reputation: 768

First of all don't make function with the same name as base R functions. I just had a problem with that. I created a test round() function for you and it got saved in R environment and i didn't know it. When i called base R round() function it actually called my test round() function. Code gave me some error. I restarted R several times with no luck. I finally realized that earlier i had created a test round() function and i deleted it manually from R Environment then things got solved.

Anyway here is your answer:

library(dplyr)
# test data as in question
round_fun <- function(x) {
  x %>% 
    mutate(new_number = ifelse((geo_lev =='USA' & 
                     reg_lev !='two'), round(number,-1), number))
  }

Output:

# A tibble: 5 x 4
  geo_lev reg_lev number new_number
  <chr>   <chr>    <dbl>      <dbl>
1 USA     one        101        100
2 France  two         10         10
3 England one         14         14
4 Ukraine two         19         19
5 Poland  one         22         22

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388982

You could do

new_round <- function(df) {
   with(df, ifelse(geo_lev =='USA' & reg_lev !='two', round(number, -1), number))
}

df1$number <- new_round(df1)
df1
# A tibble: 5 x 3
#  geo_lev reg_lev number
#  <chr>   <chr>    <dbl>
#1 USA     one        100
#2 France  two         10
#3 England one         14
#4 Ukraine two         19
#5 Poland  one         22

Or a we could pass columns individually

new_round <- function(geo_lev, reg_lev, number) {
   ifelse(geo_lev =='USA' & reg_lev !='two', round(number, -1), number)
}

library(dplyr)
df1 %>% mutate(round1 = new_round(geo_lev, reg_lev, number))

Upvotes: 1

Related Questions