Reputation: 151
I have a simulation model that takes parameters.
Instead of passing all parameters to a main function (which is complicated for the user since the dimensions of some of the parameters depend on themselves, e.g. if n=2
, vec_n
is length 2), I wanted an internal PARAMETERS object within the package, which all functions could access, and the users can change.
I made a package Test
with two functions and an internal list INTERNAL=list(a=2)
which is saved in sysdata.rda.
test_function<-function(b){
INTERNAL$a = b
print(INTERNAL)
second_function()
}
second_function<-function(){
print(INTERNAL$a)
}
However on loading the package, and running it I get the following output:
> test_function(5)
$a
[1] 5
[1] 2
Clearly, the object itself doesn't change outside the function.
I'd appreciate any help / advice in getting this to work.
Upvotes: 0
Views: 190
Reputation: 44927
INTERNAL$a = b
creates a local copy of INTERNAL
in your function, and modifies that. Since you want to modify the global copy, you could use
INTERNAL$a <<- b
but this is a bad idea, and probably wouldn't work in a package: you can't modify most values in a package after it is installed.
Alternatives to this are to make INTERNAL
into an environment (which you can modify), or create a function that returns the values you want, e.g.
INTERNAL <- function(a = "default", b = "default") {
list(a = a, b = b)
}
INTERNAL(a = 2)
#> $a
#> [1] 2
#>
#> $b
#> [1] "default"
Created on 2021-04-19 by the reprex package (v1.0.0)
You can combine these two ideas:
INTERNAL <- local({
saved <- list(a = "default", b = "default")
function(...) {
saved <<- modifyList(saved, list(...))
saved
}
})
INTERNAL(a = 1)
#> $a
#> [1] 1
#>
#> $b
#> [1] "default"
INTERNAL(b = 2)
#> $a
#> [1] 1
#>
#> $b
#> [1] 2
INTERNAL(c = 3)
#> $a
#> [1] 1
#>
#> $b
#> [1] 2
#>
#> $c
#> [1] 3
Created on 2021-04-19 by the reprex package (v1.0.0)
Upvotes: 1