Как присвоить аргумент функции имени переменной

#r #function #variables #tidyverse #variable-assignment

Вопрос:

Скажите, что у меня есть эти данные:

 data <- data.frame(a = c(1,2,3))
 

И простая функция, которая создает фрейм данных. Он также создает новую переменную на основе простой функции; эта новая переменная принимает имя, с которым она передается varname . Вот моя попытка ( assign строка неверна):

 fun <- function(varname) {
    data <- data.frame(a = c(1,2,3))
    assign(paste0("data$", varname), sqrt(data$a))  
    data
}

fun("newvar")
 

Решения Base R или tidyverse оба великолепны.

Ответ №1:

Вы были близки! Существует несколько способов подстановки кадров данных, в том числе с использованием [[.]] обозначения (например, data[["var"]] . Простое присвоение значения новому столбцу инициализирует столбец.

 fun <- function(varname) {
    data <- data.frame(a = c(1,2,3))
    data[[varname]] <- sqrt(data$a)
    data
}

fun("newvar")
 

Ответ №2:

tidyverse

Если вы хотите передать имя переменной в виде строки, то tidyverse метод будет:

 library(dplyr)

fun <- function(varname) {
  data.frame(a = c(1,2,3)) %>% 
    mutate(!! varname := sqrt(a))
}

fun("newvar")
 

В качестве альтернативы вы можете использовать tidyeval, чтобы вам не нужно было указывать имя переменной:

 library(dplyr)

fun <- function(varname) {
  varname <- rlang::enquo(varname)
  data.frame(a = c(1,2,3)) %>% 
    mutate(!! varname := sqrt(a))
}

fun(newvar)
 

основание R

Если вы хотите использовать базу R, я бы рекомендовал решение, опубликованное @Noah, но другим вариантом базы R, который является довольно тупым, было бы:

 fun <- function(varname) {
  data.frame(a = c(1,2,3)) |>
    within(eval(substitute(x <- sqrt(a), list(x = as.name(varname)))))
}

fun("newvar")
 

Комментарии:

1. Здорово. Почему двойной !!?

2. @bill999 Что ты имеешь в виду, почему двойной?

3. Извините, я имел в виду, почему в строке «tidyverse «»мутировать» есть два восклицательных знака.

4. !! И := -это синтаксис, который вы используете для оценки varname перед созданием переменной. В противном случае имя новой переменной будет varname вместо newvar . Более подробную информацию смотрите на странице справки: ?`!!`

5. Я займусь этим вопросом. Спасибо!