Home > other >  Use input of a function as variable name in R
Use input of a function as variable name in R

Time:06-16

I have a simple function in R to modify a dataframe

monthly_fun <- function(x){
x  %>% 
  mutate(obstime = convert_dates(obstime)) %>% 
  select(obstime, x = obsvalue)
}

When applying the function to dataframe df, i.e. monthly_fun(df), I would like df to be the name of obsvalue. In my current code, the name is obviously "x", how can I modify the part in select to get the name of the supplied dataframe as the variable name instead?

Thanks a lot

EDIT: I want to apply this function to several dataframes using

result <- list( df1, df2, df3) %>%
    lapply( monthly_fun )

CodePudding user response:

You could extract the name of input by deparse(substitute(x)), and use !!y := obsvalue in mutate().

monthly_fun <- function(x) {
  y <- deparse(substitute(x))
  x  %>% 
    mutate(obstime = convert_dates(obstime),
           !!y := obsvalue) %>% 
    select(obstime, y)
}

A simplified example:

fun <- function(x) {
  y <- deparse(substitute(x))
  x  %>% 
    mutate(!!y := 1) %>% 
    select(y)
}

fun(df)

#       df
#  1     1
#  2     1
#  3     1
#  4     1
#  5     1

Update

If you want to apply it to several data frames stored in a list, you should design a 2-argument function, one argument for data and the other for new column names. Then use Map() to apply this function over each pair of data and names.

fun <- function(x, y) {
  x %>% 
    mutate(!!y := 1) %>% 
    select(y)
}

Map(fun, list(df1, df2), c("name1", "name2"))

# [[1]]
#     name1
# 1       1
# 2       1
# 3       1
# 4       1
# 5       1
#
# [[2]]
#     name2
# 1       1
# 2       1
# 3       1
# 4       1
# 5       1

If you're familiar with purrr, The use of Map can be replaced with map2() or imap(). (Notice the difference of inputs to the both functions)

library(purrr)

# (1) map2(): Input data and names separately
map2(list(df1, df2), c("name1", "name2"), fun)

# (2) imap(): Input a named list
imap(list(name1 = df1, name2 = df2), fun)

CodePudding user response:

Using the suggestion by Julien and creating a variable using deparse(substitute(df)) and rename using that.

monthly_fun <- function(x) {
  y = deparse(substitute(x))
     x <- x %>% 
         mutate(obstime = obstime*5) %>%
         select(obstime, obsvalue)
     names(x)[names(x) == "obsvalue"] <- y
     return(x)
}

see this site for more naming methods.

  • Related