attach() inside function
Asked Answered
A

4

21

I'd like to give a params argument to a function and then attach it so that I can use a instead of params$a everytime I refer to the list element a.

run.simulation<-function(model,params){
attach(params)
#
# Use elements of params as parameters in a simulation
detach(params)
}

Is there a problem with this? If I have defined a global variable named c and have also defined an element named c of the list "params" , whose value would be used after the attach command?

Apologete answered 26/4, 2011 at 23:49 Comment(0)
N
25

Noah has already pointed out that using attach is a bad idea, even though you see it in some examples and books. There is a way around. You can use "local attach" that's called with. In Noah's dummy example, this would look like

with(params, print(a))

which will yield identical result, but is tidier.

Nauseating answered 27/4, 2011 at 7:29 Comment(3)
+1 Worth explaining what with() and within() do. In the example given, with() creates an environment from params and then evaluates the expression print(a) inside that environment. Hence the components of params are visible when the expression is evaluated, without needing to attach() them.Packthread
Thank you very much for the lucid answers.Apologete
So what worked in the end was 'myFun <-function(model,params){with(params),{...}}' where ... is the function bodyApologete
S
11

Another possibility is:

run.simulation <- function(model, params){
    # Assume params is a list of parameters from 
    # "params <- list(name1=value1, name2=value2, etc.)"
    for (v in 1:length(params)) assign(names(params)[v], params[[v]])
    # Use elements of params as parameters in a simulation
}
Storms answered 16/7, 2012 at 13:41 Comment(0)
P
8

Easiest way to solve scope problems like this is usually to try something simple out:

a = 1
params = c()
params$a = 2
myfun <- function(params) {
  attach(params)
  print(a)
  detach(params)
}
myfun(params)

The following object(s) are masked _by_ .GlobalEnv:

a

# [1] 1

As you can see, R is picking up the global attribute a here.

It's almost always a good idea to avoid using attach and detach wherever possible -- scope ends up being tricky to handle (incidentally, it's also best to avoid naming variables c -- R will often figure out what you're referring to, but there are so many other letters out there, why risk it?). In addition, I find code using attach/detach almost impossible to decipher.

Predetermine answered 27/4, 2011 at 1:8 Comment(0)
T
0

Jean-Luc's answer helped me immensely for a case that I had a data.frame Dat instead of the list as specified in the OP:

for (v in 1:ncol(Dat)) assign(names(Dat)[v], Dat[,v])

Tramel answered 6/2, 2019 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.