Есть ли способ указать имя столбца в качестве аргумента? - PullRequest
1 голос
/ 14 апреля 2020

Допустим, я хочу создать функцию, которая реплицирует выбранный столбец, для примера.

testdata <- data.frame(
  "diff1" = c(seq(1:10)),
  "diff2" = c(seq(21:30))
)

goal <- testdata %>%
  mutate(newdiff1 = diff1)

Поэтому я создаю функцию

funtest <- function(dat,var,newvar){
  dat %>%
    mutate(newvar = var)
}

однако,

test2 <- funtest(testdata,diff1,newdiff1)

вернет ошибку:

 Error: object 'diff1' not found 

Этот формат работает

nondesiredformat <- funtest(testdata,testdata$diff1,newdiff1)

, но это приведет к тому, что новая переменная будет всегда называться "newvar", вместо нашего третьего аргумента.

есть ли способ изменить функцию, чтобы аргументы в test2 могли работать?

Спасибо

Ответы [ 3 ]

1 голос
/ 14 апреля 2020

Вы можете использовать bquote для этого:

eval(bquote(
  dat %>% 
    mutate(.(newvar) := .(var))
))

Вы также можете обновить старую школу в вашем конкретном случае

dat[[newvar]] = dat[[var]]
1 голос
/ 14 апреля 2020

В функции мы можем использовать {{}} для выполнения оценки, т. Е. !! + enquo для имен переменных без кавычек, передаваемых в функцию, и для присваивания используйте := вместо =

funtest <- function(dat,var,newvar){
   dat %>%
     mutate({{newvar}} := {{var}})
        }
funtest(testdata, diff1, newdiff1)
#    diff1 diff2 newdiff1
#1      1     1        1
#2      2     2        2
#3      3     3        3
#4      4     4        4
#5      5     5        5
#6      6     6        6
#7      7     7        7
#8      8     8        8
#9      9     9        9
#10    10    10       10
0 голосов
/ 14 апреля 2020

Если вы начнете писать функции с именами переменных с аргументами, data.table может оказаться более удобным, чем dplyr. Я недавно написал пост на эту тему . По моему мнению, стандартную оценку легче обрабатывать с data.table, чем dplyr.

С data.table у вас есть несколько способов использовать имена столбцов в качестве аргумента

Использование get

Вы можете использовать get, который отображает имя со значением в определенной области. Здесь область действия вашего data.table:

library(data.table)
funtest <- function(dat,var,newvar){
  dat[, (newvar) := get(var)]
}

:= является оператором обновления по ссылке. Если вы хотите узнать больше об этом, data.table виньетки являются хорошим местом для начала. Вызов функции:

dt = data.table(iris)

funtest(dt, "Species","x")[]
     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species         x
  1:          5.1         3.5          1.4         0.2    setosa    setosa
  2:          4.9         3.0          1.4         0.2    setosa    setosa
  3:          4.7         3.2          1.3         0.2    setosa    setosa
  4:          4.6         3.1          1.5         0.2    setosa    setosa
  5:          5.0         3.6          1.4         0.2    setosa    setosa
 ---                                                                      
146:          6.7         3.0          5.2         2.3 virginica virginica
147:          6.3         2.5          5.0         1.9 virginica virginica
148:          6.5         3.0          5.2         2.0 virginica virginica
149:          6.2         3.4          5.4         2.3 virginica virginica
150:          5.9         3.0          5.1         1.8 virginica virginica

Использование .SD

Вы также можете использовать .SD, что означает Подмножество данных . Это удобнее, когда у вас есть несколько переменных в кавычках. Это позволяет избежать !!!rlang::sym, необходимого для dplyr.

. Вы можете выполнять сложные вычисления с очень кратким синтаксисом:

df[, newcolnames := lapply(.SD, mean), by = grouping_var, .SDcols = xvars]
...