Home > other >  Change R data frame within a function? Why alteration of df causing assign() to fail?
Change R data frame within a function? Why alteration of df causing assign() to fail?

Time:01-16

Is it possible to change an R data frame within a function without calling the function from a reference to that object?

For example, say I have a function character_func() that I want to change data frames like mtcars2 so that mpg becomes a character value.

I would like to just use: character_func(mtcars2) EDIT: so without assigning the function to an object.

The deparse-substitute trick in this solution is not working.

Example:

mtcars2 <- mtcars
character_func <- function(df) {
  df <- df %>%
    mutate(mpg_c = as.character(mpg))
  ## WARNING occurs when next line runs
  assign(deparse(substitute(df)), df)
}

character_func(mtcars2)

The assign() call returns the warning:

In assign(deparse(substitute(df)), df) :
  only the first element is used as variable name

CodePudding user response:

We need to use the deparse/substitute at the start

library(dplyr)
character_func <- function(df) {
  nm1 <- deparse(substitute(df))
  
  df <- df %>%
    mutate(mpg_c = as.character(mpg))
 
  assign(nm1, df, .GlobalEnv)
}

-testing

> character_func(mtcars2)
> 
> str(mtcars2)
'data.frame':   32 obs. of  12 variables:
 $ mpg  : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl  : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp : num  160 160 108 258 360 ...
 $ hp   : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat : num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt   : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec : num  16.5 17 18.6 19.4 17 ...
 $ vs   : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am   : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear : num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb : num  4 4 1 1 2 1 4 2 2 4 ...
 $ mpg_c: chr  "21" "21" "22.8" "21.4" ...

CodePudding user response:

Could you not do something like this using return()?:

mtcars2 <- mtcars
character_func <- function(df) {
  df <- df %>%
    mutate(mpg = as.character(mpg))
  return(df)
}

df_chr <- character_func(mtcars2)
type_of(df_chr$mpg)

output:

[1] "character"

Edit

mtcars2 <- mtcars
character_func <- function(df) {
df_sym <-ensym(df)
df_char <- as_string(df_sym)
df_2 <- df %>%
  mutate(mpg = as.character(mpg))

assign(df_char, df_2, inherits=TRUE)

}
character_func(mtcars2)
type_of(mtcars2$mpg)
  •  Tags:  
  • r
  • Related