Динамическое создание имен аргументов - PullRequest
1 голос
/ 03 октября 2019

Возможно ли в R динамическое создание имен аргументов в вызове функции?

Например, если мы начнем с

name <- "variable"

, я хотел бы создать новый фрейм данных, напримерэто

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

, которое, конечно, не работает.

Единственное решение, которое я мог придумать, было

arg <- list(c(1, 2))
names(arg) <- name
a.new.data.frame <- do.call(data.frame, arg)
a.new.data.frame
#  variable
#1        1
#2        2

Мне не нравится этот код, так как он кажется не изящным.

Есть ли лучший способ сделать это?

PS Важно! Это более общая проблема, с которой я сталкиваюсь при написании R-программ (например, когда я использую ggplot и во многих других случаях). Итак, я ожидаю общих решений для этого (создание data.frame является только примером).

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Более компактный код для динамических аргументов может выглядеть следующим образом:

df <- do.call(data.frame, list(name = c(1, 2)))

Вы можете использовать ?dotsMethods для инкапсуляции do.call в общей функции, подобной этой, чтобы сохранить шум list()часть вызова:

call.with.dyn.args <- function(f, ...) {
  args <- list(...)
  do.call(f, args)
}

df1 <- call.with.dyn.args(data.frame, a = 1:2, b = letters[1:2])
df1
# a b
# 1 1 a
# 2 2 b

Но у вас также есть другие опции для динамической передачи аргументов функциям без do.call, например ::

dyn.values <- c(1:2)
name = "dyn.values"
df2 <- data.frame(dyn.values,                     # values from a variable
                  name = dyn.values,              # values from a variable + new name
                  static.arg = letters[1:2],      # usual direct passing of an arg
                  name.from.variable = get(name)) # get the values from a variable whose name is stored in another variable
df2
#   dyn.values name static.arg name.from.variable
# 1          1    1          a                  1
# 2          2    2          b                  2
1 голос
/ 03 октября 2019

Опция, использующая tidyverse

library(tibble)
library(dplyr)
tibble(!! name := c(1, 2))
# A tibble: 2 x 1
#  variable
#     <dbl>
#1        1
#2        2
...