Reputation: 747
This may appear as a strange request, but I'm looking to essentially attach an object temporarily so that individual elements can be extracted from said object, but without actually using attach()
or with()
. For instance, I'm well aware that these two approaches are fine to index a data.frame
elements by name"
obj <- data.frame(N=2, sd=1)
myfun <- function(obj){
N2 <- obj$N^2
rnorm(N2, obj$sd)
}
myfun(obj)
myfun2 <- function(obj){
with(obj, {
N2 <- N^2
rnorm(N2, sd)
})
}
myfun2(obj)
However, what I want is something more general, where the form can be
# wanted
myfun3 <- function(){
N2 <- N^2
rnorm(N2, sd)
}
with(obj, myfun3()) #this is the idea but clearly doesn't work
so that explicitly indexing the elements of obj
is not required, and wrapping the whole statement in a with()
function can be avoided. Obviously myfun3()
doesn't locate the internals of obj
, but I would like it to. The following works fine and is exactly what I want from a functional standpoint, but is far from kosher:
attach(obj)
myfun3()
detach(obj)
Attaching is generally considered bad, and for my purpose this code has to work within an R package, so attach()
isn't even allowed (as well, it be nested within another function which can be run in parallel....so exporting to the Global Environment likely is not a good solution).
Ultimately, I would like this all to work as follows in a safe parallel computing environment
library(parallel)
cl <- makeCluster()
parfun <- function(index, obj, myfun){
out <- with(obj, myfun())
out
}
parSapply(cl=cl, 1:100, parfun, obj=obj, myfun=myfun3)
Any thoughts would be greatly appreciated.
Upvotes: 0
Views: 151
Reputation: 10167
How about:
do.with <- function(context,fun,args=list()){
env <- as.environment(context)
parent.env(env) <- environment(fun)
environment(fun) <- env
do.call(fun,args)
}
context = list(x=1,y=2)
add = function() x + y
do.with(context,add)
context = list(x=2)
parameters = list(y=5)
mult = function(y) x * y
do.with(context,mult,parameters)
Upvotes: 1