Smits N
2008-Aug-14 21:06 UTC
[R] error in passing an argument to do.call when do.call is in a for statement
Dear R-users, I am having a problem with passing an argument to a function in a do.call function which itself is in a for statement. I am building a function to upload question pools to the blackboard learning environment. This function which transforms questions to XML style output should be generic and allow for any function to generate questions. Therefore I use do.call in this function. However, because I make multiple versions of a single type of item I use a for statement. Now, when specifying a path for a jpeg (which is part of a question), this path is no longer found by the do.call statement when it is in the for loop. Consequently no jpegs are being created (my created dirs remain empty). I guess it has something to do with different environments inside and outside the do.call. I don't know how to provide them to the do.call properly. I tried to solve it by giving the path a `<<-' assignment but then only one jpeg is being created the first time, all other jpegs are not created. Maybe anyone of you can help? Here is a simplified version of the code I have been using (looks a bit silly, but the drawpic function is a bunch of code with all kinds of other functionalities, which work fine). #This function is unimportant; it generates random paths randomstring<-function(a=1,n=31){ z<-vector(length=a) for (h in 1:a){ x<-"n" for (i in 1:n){ if (runif(1)>0.5){ y<-round(runif(1,-.5,9.5)) } else {y<-letters[round(runif(1,.5,24.5))] } x<-paste(x,y, sep = "") } z[h]<-x } z } #this is a simple function to generate jpegs dp<-function(path){ jpeg(filename = path, width = 480, height = 480, pointsize = 12, quality = 85, bg = "white", res = NA, restoreConsole = TRUE) x<-rnorm(1000) hist(x) dev.off()} #this mimicks the generic function drawpic<-function(method,methodArgs,rep=5){ dir.create(paste("C:\\BB\\")) time<-format(Sys.time(), "%Y-%m-%d-%H%M") dir.create(paste("C:\\BB\\",time,sep="")) supdir<-paste("C:\\BB\\",time,sep="") for (i in 1:rep){ subdir<-randomstring() dir.create(paste(supdir,"\\",subdir,sep="")) Path<<-paste(supdir,"\\",subdir,"\\jpg.jpg",sep="")#using `<-' instead of `<<-' #does not produce any pictures x<-do.call(method,methodArgs) }} #run the small function within generic function: drawpic(method=dp,methodArgs=list(path=Path)) Hope to hear from you people, Cheers! Dr Niels Smits Taskforce Methods & Statistics Faculty of Psychology and Education Vrije Universiteit The Netherlands
Prof Brian Ripley
2008-Aug-15 06:48 UTC
[R] error in passing an argument to do.call when do.call is in a for statement
Your code is pretty much unreadable -- no spaces, not properly indented. Please see `Writing R Extensions' about how to prepare legible code. (If you want free consultancy, your potential helpers do expect this from you.) But I am prety sure that neither do.call() nor the for() loop are anything to do with this, and you needed to simplify your example much further to find the root cause. The issue seems to be that you are calling drawpic() with an argument that refers to 'Path' defined within its body, and that will not work. If you use <<-, by lazy evaluation 'Path' exists in the workspace by the time the argument is evaluated, but it is evaluated only once. You need to rethnk the design. If you want to pass in an expression to be evaluated in the evaluation frame of drawpic, you need to pass an unevaluated expression, not a value. (If you don't know what that means, maybe you should try to do something less ambitiously general?) (It seems to me that the topic would become more suitable for the R-devel list.) On Thu, 14 Aug 2008, Smits N wrote:> > > Dear R-users, > > I am having a problem with passing an argument to a function in a > do.call function which itself is in a for statement. > > > I am building a function to upload question pools to the blackboard > learning environment. This function which transforms questions to XML > style output should be generic and allow for any function to generate > questions. Therefore I use do.call in this function. However, because I > make multiple versions of a single type of item I use a for statement. > Now, when specifying a path for a jpeg (which is part of a question), > this path is no longer found by the do.call statement when it is in the > for loop. Consequently no jpegs are being created (my created dirs > remain empty). I guess it has something to do with different > environments inside and outside the do.call. I don't know how to provide > them to the do.call properly. I tried to solve it by giving the path a > `<<-' assignment but then only one jpeg is being created the first time, > all other jpegs are not created. Maybe anyone of you can help? > > Here is a simplified version of the code I have been using (looks a bit > silly, but the drawpic function is a bunch of code with all kinds of > other functionalities, which work fine). > > > #This function is unimportant; it generates random paths > randomstring<-function(a=1,n=31){ > z<-vector(length=a) > for (h in 1:a){ > x<-"n" > for (i in 1:n){ > if (runif(1)>0.5){ > y<-round(runif(1,-.5,9.5)) > } > else {y<-letters[round(runif(1,.5,24.5))] > } > x<-paste(x,y, sep = "") > } > z[h]<-x } > z > } > > > > #this is a simple function to generate jpegs > dp<-function(path){ > jpeg(filename = path, width = 480, height = 480, > pointsize = 12, quality = 85, bg = "white", > res = NA, restoreConsole = TRUE) > x<-rnorm(1000) > hist(x) > dev.off()} > > #this mimicks the generic function > drawpic<-function(method,methodArgs,rep=5){ > dir.create(paste("C:\\BB\\")) > time<-format(Sys.time(), "%Y-%m-%d-%H%M") > dir.create(paste("C:\\BB\\",time,sep="")) > supdir<-paste("C:\\BB\\",time,sep="") > for (i in 1:rep){ > subdir<-randomstring() > dir.create(paste(supdir,"\\",subdir,sep="")) > Path<<-paste(supdir,"\\",subdir,"\\jpg.jpg",sep="")#using `<-' instead of `<<-' > #does not produce any pictures > x<-do.call(method,methodArgs) > }} > > > #run the small function within generic function: > drawpic(method=dp,methodArgs=list(path=Path)) > > > Hope to hear from you people, > > Cheers! > > > > > Dr Niels Smits > Taskforce Methods & Statistics > Faculty of Psychology and Education > Vrije Universiteit > The Netherlands > > ______________________________________________ > 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. >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595