Я пытаюсь использовать пакет sqldf
внутри определяемой пользователем функции в r с общими именами столбцов. Я могу заставить его работать только в том случае, если имена переменных совпадают с именами переменных-заполнителей (x
и y
) внутри функции. Однако я хочу, чтобы он работал независимо от имени переменной, переданной в функцию. Вот пример, с которым я играл:
Вот форма, которая работает:
df<-data.frame(X=as.factor(c("a","a","a","b","b","b","c","c","c")), Y=c(2.5,3,4,4,5.3,6,6.555,7,8))
df
Bar_Prep1<-function(data,x,y){
library(sqldf)
require(sqldf)
dataframe<-sqldf("select a.[x] Grp, AVG(a.[y]) Mean, stdev(a.[y]) SD, Max(a.[y]) Max
from data a
group by a.[x]")
dataframe$RD<-round(dataframe$Mean,digits=0)
return(dataframe)
}
test<-Bar_Prep1(df,df$X,df$Y)
test
Что возвращает следующий df:
Grp Mean SD Max RD
1 a 3.166667 0.7637626 4 3
2 b 5.100000 1.0148892 6 5
3 c 7.185000 0.7400507 8 7
НО, я хочу иметь возможность использовать эту функцию для разных имен столбцов, поэтому я попробовал это:
df1<-data.frame(a=as.factor(c("a","a","a","b","b","b","c","c","c")), b=c(2.5,3,4,4,5.3,6,6.555,7,8))
df1
test1<-Bar_Prep1(df1,df1$a,df1$b)
test1
Возвращает следующие ошибки: «Ошибка: нет такого столбца: a.x» "объект 'test1' не найден
Итак, вопрос в том, как мне изменить код моей функции, чтобы он принимал имена переменных, отличные от «x» и «y»?
Передавайте имена, а не столбцы. Измените вызов sqldf
на fn$sqldf
, что позволит интерполировать строки с помощью $. Затем в выражении select
используйте $x
и $y
.
library(sqldf)
Bar_Prep1 <- function(data, x, y) {
dataframe <- fn$sqldf("select
a.[$x] Grp,
AVG(a.[$y]) Mean,
stdev(a.[$y]) SD,
Max(a.[$y]) Max
from data a
group by a.[$x]")
dataframe$RD <- round(dataframe$Mean, digits = 0)
return(dataframe)
}
Bar_Prep1(df, "X", "Y")
## Grp Mean SD Max RD
## 1 a 3.166667 0.7637626 4 3
## 2 b 5.100000 1.0148892 6 5
## 3 c 7.185000 0.7400507 8 7
Обратите внимание, что можно было бы включить округление в оператор SQL:
Bar_Prep1 <- function(data, x, y) {
fn$sqldf("with tmp as (select
a.[$x] Grp,
AVG(a.[$y]) Mean,
stdev(a.[$y]) SD,
Max(a.[$y]) Max
from data a
group by a.[$x])
select *, round(Mean) RD from tmp")
}
К сожалению, я пробовал обе формы, и ни одна из них не работала. Когда я попытался вызвать их через Bar_Prep1(df1,df1$a, df1$b), они вернули следующее сообщение: Ошибка: нет такого столбца a.c(1,1,1,2,2,2,3,3,3) . Когда я связал вызов их через Bar_Prep1(df1,a,b), сообщение об ошибке изменилось на: Ошибка в eval(parse(text = paste(..., sep = "")), env): объект 'a' not найденный. Так что не совсем уверен, что здесь происходит. Я собираюсь попробовать перезапустить.
Как говорится в ответе, и пример в ответе показывает, что вы должны передавать имена в виде строк символов. Если в df1 есть столбцы с именами a и b, используйте Bar_Prep1(df1, "a", "b")
. Вы забыли цитаты.
Да, я сделал, не так ли. Отлично. Ваше здоровье!
Великолепно! Огромное спасибо за помощь. Действительно ценю это. Ваше здоровье! п