Простой воспроизводимый пример для передачи аргументов в data.table в самоопределяемой функции в R - PullRequest
4 голосов
/ 31 октября 2019

Я гуглю этот ответ в течение нескольких часов. Многие люди задавали подобные вопросы, но я не нашел ни достаточно простого вопроса, ни однозначного ответа. Вот мой подход:

Предположим, что я хочу создать простую группу в data.table:

library(data.table)
mtcars = data.table(mtcars)
mtcars[,sum(mpg), gear]

# Here are the results
#   gear    V1
#1:    4 294.4
#2:    3 241.6
#3:    5 106.9

Однако, если я использую для этого определенную пользователем функцию:

zz = function(data, var, group){
  return(data[,sum(var), group])
}
zz(mtcars, mpg, gear)

Я получил сообщение об ошибке:

Ошибка в eval (bysub, parent.frame (), parent.frame ()): объект 'gear' не найден

Я пробовал substitute, eval, quote и другие решения, но ни одно из них не работает. Интересно, кто-нибудь мог бы дать более простое решение и объяснение этому.

Спасибо и счастливого Хэллоуина!

Ответы [ 2 ]

5 голосов
/ 31 октября 2019

Если мы используем аргументы без кавычек, substitute и eval uate

zz <- function(data, var, group){
 var <- substitute(var)
 group <- substitute(group)
 setnames(data[, sum(eval(var)), by = group],
        c(deparse(group), deparse(var)))[]
 # or use
 #  setnames(data[, sum(eval(var)), by = c(deparse(group))], 2, deparse(var))[]

}
zz(mtcars, mpg, gear)
#   gear   mpg
#1:    4 294.4
#2:    3 241.6
#3:    5 106.9
4 голосов
/ 01 ноября 2019

Хотя и не идеально, аргумент ... может быть полезен:

zz = function(dt, ...){
  return(dt[...])
}

zz(mtcars, , sum(mpg), gear)

   gear    V1
1:    4 294.4
2:    3 241.6
3:    5 106.9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...