Alex
Alex

Reputation: 11

"Error in eval(predvars, data, env) : object 'a' not found" in function

I have code in R I want to run for many variables to get descriptive statistics, so I'd like to create a function to make my code cleaner.

The code I first run for variable without trying with a function works well:

variable1 <- prop.table(svytable(~variable, ebase2mref))
variable2 <- as.data.frame(table(base$variable))
write.table(variable1 , file = "table.csv", sep = ",", append = TRUE)
write.table(variable2 , file = "table.csv", sep = ",", append = TRUE)

but when I try to run

e2m_desc <- function(a) {
  a1 <- prop.table(svytable(~a, ebase2mref))
  a2 <- as.data.frame(table(base$a))
  write.table(a1 , file = "table.csv", sep = ",", append = TRUE)
  write.table(a2 , file = "table.csv", sep = ",", append = TRUE)
}

e2m_desc(variable)

I get error "Error in eval(predvars, data, env) : object 'a' not found".

Code run beforehand for survey weights:

ebase2mrefdep <- base %>%
  drop_na(M02E_PONDREFC2)
ebase2mref <- svydesign(ids = ~1, data = ebase2mrefdep, weights = ~ ebase2mrefdep$M02E_PONDREFC2)

I've tried replacing a with some other name, tried with other variables. I also tried running the function with one line at a time, to try and isolate a problem with one of the lines, which gave the following:

e2m_desc <- function(a) {
  a1 <- prop.table(svytable(~a, ebase2mref))
}

e2m_desc(variable)

&

e2m_desc <- function(a) {
  a1 <- prop.table(svytable(~a, ebase2mref))
  write.table(a1 , file = "table.csv", sep = ",", append = TRUE)
}

e2m_desc(variable)

: gave error "Error in eval(predvars, data, env) : object 'a' not found"

e2m_desc <- function(a) {
  a2 <- as.data.frame(table(base$a))
  write.table(a2 , file = "table.csv", sep = ",", append = TRUE)
}

e2m_desc(variable)

: while this worked

Hope this is clear enough!

Thanks!

Upvotes: 1

Views: 1744

Answers (1)

Thomas Lumley
Thomas Lumley

Reputation: 2765

I'm surprised that your last one worked: base$a should return NULL unless there's a column called a.

Anyway, your problem is that you want to use a in a way that's not really natural in R. You want to extract the name of the actual argument (variable) without evaluating it, and then substitute it into two different expressions. That is, you're looking for a macro rather than a function.

It would be easier if you supplied some quoted form of the variable name as the argument: "a" or ~a

f1<-function(string_a){
   formula<-make.formula(string_a)
   variable1 <- prop.table(svytable(formula, ebase2mref))
   variable2 <- as.data.frame(table(base[[string_a]]))
}

or

f1<-function(tilde_a){
   variable1 <- prop.table(svytable(tilde_a, ebase2mref))
   string_a<-tilde_a[[2]]
   variable2 <- as.data.frame(table(base[[string_a]]))
}

You can, however, do what you want to do with bquote

f1<-function(a){
   a <- substitute(a)
   variable1 <- eval(bquote(prop.table(svytable(~.(a), ebase2mref))
   variable2 <- eval(bquote(with(base, as.data.frame(table(.(a))))))
}

The switch from base$a to with(base, a) is because the $ selector is sufficiently special that even bquote can't substitute into it.

Upvotes: 0

Related Questions