Max Brehmer
Max Brehmer

Reputation: 31

Using function arguments as column names

I want to create a function that takes the arguments as column names in my dataset.

However when I pass this function with my desired column names as arguments the mutated columns use the literal argument name instead of the passed column names (parameter instead of "cpp").

vehicle <- c("airplane", "bus", "car")
people <- c(300, 40, 5)
cost <- c(50, 5, 2)

small_dataset <- data.frame(vehicle, people, cost)

func <- function(data, parameter) {
  data <- data %>%
    mutate(parameter = cost/people)
  return(data)
}

func(small_dataset, "cpp")
WHAT I WANT:
##    vehicle people cost cpp
## 1 airplane    300   50 0.1666667
## 2      bus     40    5 0.1250000
## 3      car      5    2 0.4000000

WHAT I GET:
##    vehicle people cost parameter
## 1 airplane    300   50 0.1666667
## 2      bus     40    5 0.1250000
## 3      car      5    2 0.4000000

How do I get the function to use the arguments as column names?

Upvotes: 3

Views: 1456

Answers (3)

jpdugo17
jpdugo17

Reputation: 7116

Because a data.frame is a special kind of list, we can use the purrr::set_names functions like this. Although is not very clean.

library(purrr)
library(dplyr)

func <- function(data, parameter) {
  data <- data %>%
    mutate(parameter = cost / people) %>%
    {
      set_names(., c(names(.[-ncol(.)]), parameter))
    }
  return(data)
}

func(small_dataset, "cpp")
#>    vehicle people cost       cpp
#> 1 airplane    300   50 0.1666667
#> 2      bus     40    5 0.1250000
#> 3      car      5    2 0.4000000

Created on 2022-01-04 by the reprex package (v2.0.1)

Upvotes: 0

s_baldur
s_baldur

Reputation: 33603

Perhaps cleaner here to use base R (instead of dplyr):

func <- function(data, parameter) {
  data[[parameter]] <- with(data, cost/people)
  data
}
func(small_dataset, "cpp")
#    vehicle people cost       cpp
# 1 airplane    300   50 0.1666667
# 2      bus     40    5 0.1250000
# 3      car      5    2 0.4000000

Upvotes: 3

user438383
user438383

Reputation: 6227

There are at least two options. Either use {} syntax:

library(glue)
func <- function(data, parameter) {
  data %>%
    mutate({{parameter}} := cost/people)
}
> func(small_dataset, "cpp")
   vehicle people cost       cpp
1 airplane    300   50 0.1666667
2      bus     40    5 0.1250000
3      car      5    2 0.4000000

Or the bang-bang operator !!

func <- function(data, parameter) {
  data %>%
    mutate(!!parameter := cost/people)
}
> func(small_dataset, "cpp")
   vehicle people cost       cpp
1 airplane    300   50 0.1666667
2      bus     40    5 0.1250000
3      car      5    2 0.4000000

Upvotes: 1

Related Questions