Sacha Viquerat
2011-Feb-27 20:48 UTC
[R] accessing variables inside a function, inside a loop
dear list! I KNOW this has been answered a million times before. But, as some might remember from their "freelance" times as a statistic consultant, sometimes you're blinded by the facts. I KNOW I have seen this problem solved, but due to the mental blockade i have been suffering from the last 3 hours, I can neither find the answer on the mailing list nor on google. I wrote a function to plot one continuous variable against an abundance of fish, the data is called water. however, my data covers 9 parameters, and since I am lazy as hell, I decided to write a for loop to pass all the variables to the function. as usual, the variables and the data frame cannot be found inside the function. water<-read.csv("Henni/water-abundance2.csv",sep="\t",header=T) source("functions.R") attach(water) names(water): [1] "site" "sample" "temp" "pH" "DO" "BOD" [7] "COD" "no3" "no2" "po4" "N_male" "N_female" vars<-names(water)[3:10] par(mfrow=c(4,2)) for (i in vars) { comp.plot(i,N_male,DATA=water) } comp.plot<-function(parameter,y,DATA){ #this is actually in functions.R x<-DATA[[parameter]] y<-DATA[[y]] plot(y~parameter) } and of course, this doesn't work. I am really frustrated by now, since I have gathered all I could recollect from my past 2 years of R experience but still, I was not able to find a solution. I'm really dizzy right now, but since I will not be able to go to sleep unless I have found the answer to this problem, I urge someone to shed some light on my trivial problem! I will promise not to post this question ever again, but for now, I'm just stuck! Thanks in advance and humble apologies to all that feel offended by my post!
jim holtman
2011-Feb-27 21:18 UTC
[R] accessing variables inside a function, inside a loop
A quick look says you are passing N_Male in which is a vector of values, but you are trying to use it as if it were a character value in: y <- DATA[[y]] try calling it with comp.plot(i,"N_male",DATA=water) Also get out of the habit of using 'attach'; it can lead to other issues. On Sun, Feb 27, 2011 at 3:48 PM, Sacha Viquerat <tweedie-d at web.de> wrote:> dear list! > I KNOW this has been answered a million times before. But, as some might > remember from their "freelance" times as a statistic consultant, sometimes > you're blinded by the facts. I KNOW I have seen this problem solved, but due > to the mental blockade i have been suffering from the last 3 hours, I can > neither find the answer on the mailing list nor on google. I wrote a > function to plot one continuous variable against an abundance of fish, the > data is called water. however, my data covers 9 parameters, and since I am > lazy as hell, I decided to write a for loop to pass all the variables to the > function. as usual, the variables and the data frame cannot be found inside > the function. > > water<-read.csv("Henni/water-abundance2.csv",sep="\t",header=T) > source("functions.R") > attach(water) > > names(water): > ?[1] "site" ? ? "sample" ? "temp" ? ? "pH" ? ? ? "DO" ? ? ? "BOD" > ?[7] "COD" ? ? ?"no3" ? ? ?"no2" ? ? ?"po4" ? ? ?"N_male" ? "N_female" > > vars<-names(water)[3:10] > > par(mfrow=c(4,2)) > for (i in vars) > { > ? ?comp.plot(i,N_male,DATA=water) > } > > comp.plot<-function(parameter,y,DATA){ #this is actually in functions.R > ? ?x<-DATA[[parameter]] > ? ?y<-DATA[[y]] > ? ?plot(y~parameter) > } > > and of course, this doesn't work. I am really frustrated by now, since I > have gathered all I could recollect from my past 2 years of R experience but > still, I was not able to find a solution. I'm really dizzy right now, but > since I will not be able to go to sleep unless I have found the answer to > this problem, I urge someone to shed some light on my trivial problem! I > will promise not to post this question ever again, but for now, I'm just > stuck! > > Thanks in advance and humble apologies to all that feel offended by my post! > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Jim Holtman Data Munger Guru What is the problem that you are trying to solve?
Joshua Wiley
2011-Feb-27 21:50 UTC
[R] accessing variables inside a function, inside a loop
Dear Sacha, That is the most piteous soliloquy I have read in some time. Here then a response to soothe your dizzied mind and wrest your rest from the ornery sprites that so threaten to plague it now. ## Some sample data water <- as.data.frame(matrix(rnorm(120), ncol = 12)) ## Adding your names names(water) <- c("site", "sample", "temp", "pH", "DO", "BOD", "COD", "no3", "no2", "po4", "N_male", "N_female") par(mfrow = c(4, 2)) ## Simplest lapply(water[, 3:10], FUN = plot, y = water[, "N_male"]) ## Slightly fancier plotter <- function(x) { form <- eval(substitute(N_male ~ p, list(p = as.name(x)))) plot(form, data = water) } ## lapply(names(water[, 3:10]), plotter) ## Or if you wanted to start getting "really" fancy ## you could wrap it all up jwrap <- function(y, x, dat, mfrow) { old.par <- par(no.readonly = TRUE) on.exit(old.par) par(ask = TRUE, mfrow = mfrow) jplot <- function(x, y) { form <- eval(substitute(y ~ p, list(y = as.name(y), p = as.name(x)))) plot(form, data = water) } lapply(X = names(dat[, x]), FUN = jplot, y = y) } ## jwrap() in action jwrap("N_male", x = 3:10, dat = water, mfrow = c(4, 2)) ## and showing what happens if you change mfrow jwrap("N_male", x = 3:10, dat = water, mfrow = c(2, 2)) In all good cheer, Joshua On Sun, Feb 27, 2011 at 12:48 PM, Sacha Viquerat <tweedie-d at web.de> wrote:> dear list! > I KNOW this has been answered a million times before. But, as some might > remember from their "freelance" times as a statistic consultant, sometimes > you're blinded by the facts. I KNOW I have seen this problem solved, but due > to the mental blockade i have been suffering from the last 3 hours, I can > neither find the answer on the mailing list nor on google. I wrote a > function to plot one continuous variable against an abundance of fish, the > data is called water. however, my data covers 9 parameters, and since I am > lazy as hell, I decided to write a for loop to pass all the variables to the > function. as usual, the variables and the data frame cannot be found inside > the function. > > water<-read.csv("Henni/water-abundance2.csv",sep="\t",header=T) > source("functions.R") > attach(water) > > names(water): > ?[1] "site" ? ? "sample" ? "temp" ? ? "pH" ? ? ? "DO" ? ? ? "BOD" > ?[7] "COD" ? ? ?"no3" ? ? ?"no2" ? ? ?"po4" ? ? ?"N_male" ? "N_female" > > vars<-names(water)[3:10] > > par(mfrow=c(4,2)) > for (i in vars) > { > ? ?comp.plot(i,N_male,DATA=water) > } > > comp.plot<-function(parameter,y,DATA){ #this is actually in functions.R > ? ?x<-DATA[[parameter]] > ? ?y<-DATA[[y]] > ? ?plot(y~parameter) > } > > and of course, this doesn't work. I am really frustrated by now, since I > have gathered all I could recollect from my past 2 years of R experience but > still, I was not able to find a solution. I'm really dizzy right now, but > since I will not be able to go to sleep unless I have found the answer to > this problem, I urge someone to shed some light on my trivial problem! I > will promise not to post this question ever again, but for now, I'm just > stuck! > > Thanks in advance and humble apologies to all that feel offended by my post! > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Joshua Wiley Ph.D. Student, Health Psychology University of California, Los Angeles http://www.joshuawiley.com/
Joshua Great solution. Taking off on your code, the following works but does not display the names of the variables in the formula. Any suggestions about how to modify the function so that it displays the correct formula (e.g., "glm(formula = y1 ~ x1 * x2, data = dat)" instead of "glm(formula = frm, data = dat)")? R> x = runif(2000) R> y = runif(2000) R> z = runif(2000) R> R> y1 = y * x R> y2 = y * sqrt(x) R> R> x1 = y1 / y2 + z R> x2 = y2 / y1 * z + z R> R> dat = data.frame(y1,y2,x1,x2) R> R> xReg = function(y) { + + frm = eval(substitute(p ~ x1 * x2, list(p = as.name(y)))) + mod = glm(frm, data=dat) + } R> R> lapply(names(dat[,1:2]), xReg) [[1]] Call: glm(formula = frm, data = dat) Coefficients: (Intercept) x1 x2 x1:x2 -0.1882452 0.4932059 0.0667401 -0.1310084 Degrees of Freedom: 1999 Total (i.e. Null); 1996 Residual Null Deviance: 99.15032 Residual Deviance: 67.71775 AIC: -1085.354 [[2]] Call: glm(formula = frm, data = dat) Coefficients: (Intercept) x1 x2 x1:x2 -0.005464627 0.386937367 0.037363416 -0.094136334 Degrees of Freedom: 1999 Total (i.e. Null); 1996 Residual Null Deviance: 112.7078 Residual Deviance: 90.24796 AIC: -510.9287 --- Thanks, Alan