Преобразование агрегатной функции в пользовательскую функцию

Я создал набор данных в R следующим образом:

m <- mtcars
m$dep<- ifelse(m$mpg <=16,1,0)

Теперь, если я попытаюсь суммировать переменную dep согласно группе, выполненной на основе цил

a <-aggregate(dep_var~ cyl, FUN=sum, data=m)
a

Получаю желаемый результат. Однако моя проблема в том, что если я попытаюсь преобразовать его в пользовательскую функцию для автоматизации, я получаю сообщение об ошибке. Я пробовал следующий код:

f<- function(target,variable,data){
  a <-aggregate(target ~ variable, FUN=sum, data=data)
  return(a)
}
f(dep,cyl,m)

Не могли бы вы помочь мне в этом отношении. Не могли бы вы также сказать мне, когда мне следует использовать двойные кавычки при вызове функции? Например. f ("деп", "цил", м). Я попробовал этот код для своей функции, но он тоже не сработал.

Пожалуйста, помогите мне исправить эту функцию.


person shejomamu    schedule 24.11.2015    source источник


Ответы (2)


1) В этом случае проще не использовать интерфейс формул. Сначала получите имена целей и переменных в виде символьных строк, а затем запустите aggregate:

f1 <- function(target, variable, data) {
  target <- deparse(substitute(target))
  variable <- deparse(substitute(variable))
  aggregate(data[target], data[variable], sum)
}
f1(dep, cyl, m)

давая:

  cyl dep
1   4   0
2   6   0
3   8  10

2) Если вы хотите передавать имена столбцов в виде символьных строк напрямую, а не в неоцененных выражениях, как мы делали выше, это еще проще и дает тот же результат:

f2 <- function(target, variable, data) {
  aggregate(data[target], data[variable], sum)
}
f2("dep", "cyl", m)

3) Хотя вопрос был задан для решения aggregate, на нем был тег sqldf, поэтому, если вам нужно решение sqldf, здесь будет такое решение, в котором передаются имена. Если вы хотите передать невычисленные выражения, используйте тот же подход, что и в (1) с deparse(substitute(...)):

library(sqldf)
f3 <- function(target, variable, data) {
    fn$sqldf("select $variable, sum($target) from data group by $variable")
}
f3("dep", "cyl", m)
person G. Grothendieck    schedule 24.11.2015

Вам нужно добавить as.formula в вашу функцию. Это должно дать вам желаемый результат.

f <- function(target,variable,data){
  a <- aggregate(as.formula(paste(target,variable,sep=" ~ ")), FUN = sum, data = data)
  return(a)
}

f("dep","cyl",m)
> f("dep","cyl",m)
  cyl dep
1   4   0
2   6   0
3   8  10
person s_scolary    schedule 24.11.2015
comment
Я не мог достаточно отблагодарить вас за вашу помощь. Я также хотел бы поблагодарить Г. Гротендика за демонстрацию использования SQLDF. Я как раз хотел спросить, как это сделать с помощью sqldf. Могу я задать вам еще одно предложение? Где я могу изучить способы обучения функциям, именно так, как вы показали. Есть ли какая-нибудь книга или веб-сайт, за которыми можно было бы следить? - person shejomamu; 25.11.2015