How to create a function to change data types of multiple columns?

I am trying to create a simple function I can use to change the data type of quite a few columns. For some reason, it says that object 'Dogs' not found when I try to call the function. Any ideas what I'm doing wrong?

change_type <- function (data_set, columns_to_change) 
{
  data_set <-
    data_set %>%
    mutate(columns_to_change = as.integer(columns_to_change))
}

change_type(data_set = df_imported,
            columns_to_change = Dogs)

This is basically what I am trying to put into a function:

df_imported <-
  df_imported %>%
  mutate(Dogs = as.integer(Dogs))

The Dogs column is within df_imported, and the code right above works. I'd like to sub in other columns in a function though. Any help would be appreciated.

Your function is using mutate() which uses non-standard evaluation of arguments. For example, in mutate(Dogs = as.integer(Dogs)), Dogs is used as a bare name as if it is a regular object but it is actually a column name in the data frame. mutate() is written to handle this. In your function, you pass in Dogs in the same way but R treats it as an independent object and can't find it.
In the example below, I have written two versions of your function. One uses {{ }} from rlang to handle the non-standard evaluation. The second version accepts "Dogs" with quotes so it is simply a string and is not treated as a object name.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(rlang)

#Using non-standard evaluation
change_type <- function (data_set, columns_to_change) 
{
  data_set <-
    data_set %>%
    mutate({{columns_to_change}} := as.integer({{columns_to_change}}))
  return(data_set)
}

DF <- data.frame(Dogs=c("1","2","3"))
str(DF)
#> 'data.frame':    3 obs. of  1 variable:
#>  $ Dogs: chr  "1" "2" "3"
DF <- change_type(data_set = DF,
            columns_to_change = Dogs)
str(DF)
#> 'data.frame':    3 obs. of  1 variable:
#>  $ Dogs: int  1 2 3

#Not using non-standard evaluation
change_type2 <- function (data_set, columns_to_change) {
  data_set[[columns_to_change]] <- as.integer(data_set[[columns_to_change]])
  return(data_set)
}

DF <- data.frame(Dogs=c("1","2","3"))
str(DF)
#> 'data.frame':    3 obs. of  1 variable:
#>  $ Dogs: chr  "1" "2" "3"
DF <- change_type2(data_set = DF,
                  columns_to_change = "Dogs") #Notice "Dogs" is quoted
str(DF)
#> 'data.frame':    3 obs. of  1 variable:
#>  $ Dogs: int  1 2 3

Created on 2021-12-04 by the reprex package (v2.0.1)

1 Like
DF <- data.frame(
  sex =
    c(2, 2, 1, 1),
  education =
    c(2, 2, 1, 2),
  marriage =
    c(2, 2, 2, 1),
  age =
    c(26, 41, 23, 40))

str(DF)  
#> 'data.frame':    4 obs. of  4 variables:
#>  $ sex      : num  2 2 1 1
#>  $ education: num  2 2 1 2
#>  $ marriage : num  2 2 2 1
#>  $ age      : num  26 41 23 40

to_factor <- c("sex", "education", "marriage")

DF[to_factor] <- lapply(DF[to_factor], as.factor)

str(DF)
#> 'data.frame':    4 obs. of  4 variables:
#>  $ sex      : Factor w/ 2 levels "1","2": 2 2 1 1
#>  $ education: Factor w/ 2 levels "1","2": 2 2 1 2
#>  $ marriage : Factor w/ 2 levels "1","2": 2 2 2 1
#>  $ age      : num  26 41 23 40

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.