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