[R] Preserving lists in a function

Barry Rowlingson b.rowlingson at lancaster.ac.uk
Sat Feb 27 01:06:24 CET 2010


On Fri, Feb 26, 2010 at 10:56 PM, Shang Gao <sgao at econone.com> wrote:
> Dear R users,
>
> A co-worker and I are writing a function to facilitate graph plotting in R. The function makes use of a lot of lists in its defaults.
>
> However, we discovered that R does not necessarily preserve the defaults if we were to input them in the form of list() when initializing the function.

 It does preserve the defaults, it's just that the default is a single
object. If you assign anything to that argument it becomes the full
value of the argument, as I think you discovered!

>For example, if you feed the function codes below into R:
>
> myfunction=function(
>    list1=list  (variable1=1,
>                variable2=2,
>                variable3=3),
>
>    list2=list  (variable1="variable1",
>                variable2="variable2",
>                variable3="variable3"),
>
>    list3=list  (variable1="character",
>                variable2=24,
>                variable3=c(0.1,0.1,0.1,0.1),
>                variable4=TRUE))
>
> {return(list(list1=list1,list2=list2,list3=list3))}

 What I think you need to do is to replace your lists with functions.
So you'd do:

 > arg1f
function(v1=1,v2=2,v3=3){list(v1,v2,v3)}

 for your first argument. That gives you a way of overriding some of
those arguments:

> arg1f(v2=99)
[[1]]
[1] 1

[[2]]
[1] 99

[[3]]
[1] 3

 do the same for the second argument with a new function with
different defaults:

> arg2f
function(v1=99,v2=99,v3=99){list(v1,v2,v3)}

 then define your main function to get its args from the defaults of
these functions:

> myfunction=function(a1=arg1f(),a2=arg2f())
+ {list(a1=a1,a2=a2)}

so that

 myfunction() gives:

$a1
$a1[[1]]
[1] 1

$a1[[2]]
[1] 2

$a1[[3]]
[1] 3


$a2
$a2[[1]]
[1] 99

$a2[[2]]
[1] 99

$a2[[3]]
[1] 99

 - and then you can override bits thus:

> myfunction(a1=arg1f(v2=pi))
$a1
$a1[[1]]
[1] 1

$a1[[2]]
[1] 3.141593

$a1[[3]]
[1] 3


$a2
$a2[[1]]
[1] 99

$a2[[2]]
[1] 99

$a2[[3]]
[1] 99


 - which only overrides the second part of the first argument, keeping
the defaults for everything else.

What you are saying by doing:

myfunction=function(a1=arg1f(),a2=arg2f())

 is that a1 is by default the default value of arg1f(), and similarly
for a2. It's almost like constructing an object of some type. When you
call the function you have to do a1=arg1f(v1=whatever) but that's an
advantage to just a list() call in more ways - for example your arg1f
function can check that the inputs are valid, or it can return an
object of some class you can work with.

 Hope this helps.

 Barry


-- 
blog: http://geospaced.blogspot.com/
web: http://www.maths.lancs.ac.uk/~rowlings
web: http://www.rowlingson.com/
twitter: http://twitter.com/geospacedman
pics: http://www.flickr.com/photos/spacedman



More information about the R-help mailing list