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. 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))} By definition, the values associated with each variable in the lists would be the default unless the user impute a different value while executing the function. But a problem arises when a variable in the list is left out completely (not imputed at all). An example is shown below: myfunction( list1=list (variable1=1, variable2=2), #variable 3 deliberately left out list2=list (variable1="variable1", variable3="position changed", variable2="variable2"), list3=list (variable1="character", variable2=24, variable4=FALSE)) #variable 3 deliberately left out #The outcome of the above execution is shown below: $list1 $list1$variable1 [1] 1 $list1$variable2 [1] 2 #list1$variable3 is missing. Defaults in function not assigned in this execution $list2 $list2$variable1 [1] "variable1" $list2$variable3 [1] "position changed" $list2$variable2 [1] "variable2" $list3 $list3$variable1 [1] "character" $list3$variable2 [1] 24 $list3$variable4 [1] FALSE #list3$variable3 is missing. Defaults in function not assigned in this execution We later realized that the problem lies in list() commands. Hence, we tried to enforce the defaults on the list using these codes in the function definition: myfunction.alternative=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)) { defaults=vector("list", 3) names(defaults)=c("list1","list2","list3") defaults$list1=list(variable1=1, variable2=2, variable3=3) defaults$list2=list(variable1="variable1", variable2="variable2", variable3="variable3") defaults$list3=list (variable1="character", variable2=24, variable3=c(0.1,0.1,0.1,0.1), variable4=TRUE) if(length(list1$variable1)==0){list1$variable1=defaults$list1$variable1} if(length(list1$variable2)==0){list1$variable2=defaults$list1$variable2} if(length(list1$variable3)==0){list1$variable3=defaults$list1$variable3} if(length(list2$variable1)==0){list2$variable1=defaults$list2$variable1} if(length(list2$variable2)==0){list2$variable2=defaults$list2$variable2} if(length(list2$variable3)==0){list2$variable3=defaults$list2$variable3} if(length(list3$variable1)==0){list3$variable1=defaults$list3$variable1} if(length(list3$variable2)==0){list3$variable2=defaults$list3$variable2} if(length(list3$variable3)==0){list3$variable3=defaults$list3$variable3} if(length(list3$variable4)==0){list3$variable4=defaults$list3$variable4} return(list(list1=list1,list2=list2,list3=list3))} The outcome of execution the above function with the same commands produces the results that we wanted:> myfunction.alternative( list1=list (variable1=1,+ variable2=2), #variable 3 deliberately left out + + list2=list (variable1="variable1", + variable3="position changed", + variable2="variable2"), + + list3=list (variable1="character", + variable2=24, + variable4=FALSE)) #variable 3 deliberately left out $list1 $list1$variable1 [1] 1 $list1$variable2 [1] 2 $list1$variable3 [1] 3 #list1$variable3 is assigned default despite being left out in the execution command $list2 $list2$variable1 [1] "variable1" $list2$variable3 [1] "position changed" $list2$variable2 [1] "variable2" $list3 $list3$variable1 [1] "character" $list3$variable2 [1] 24 $list3$variable4 [1] FALSE $list3$variable3 [1] 0.1 0.1 0.1 0.1 #list3$variable3 is assigned default despite being left out in the execution command Even though the function works, as you can see, the codes that enforce the defaults are very long and bulky. Such lengthy codes won't be efficient if we have a write a function containing a large number of lists. We tried to come up with ideas to try to shorten the codes, but so far none of them prove to be effective. What would be your recommendation to deal with such situation? It would be great if you would be able to help us our with this problem. We appreciate your help tremendously. Thank you. Sincerely, Shang [[alternative HTML version deleted]]
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:> arg2ffunction(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
Barry explained your first puzzle, but let me add some explanation and examples.> tmpfun <- function( a =3 ) {a} > tmpfun()[1] 3> tmpfun(a='x')[1] "x" Inside the function, the value of the argument is whatever the user supplied. The default is replaced by what the user supplies. There is no mechanism for retaining the default structure and filling in any missing parts. R never preserves the defaults when the user supplies something other than the default. For example, and using your function,> myfunction(list1='x')$list1 [1] "x" $list2 $list2$variable1 [1] "variable1" $list2$variable2 [1] "variable2" $list2$variable3 [1] "variable3" $list3 $list3$variable1 [1] "character" $list3$variable2 [1] 24 $list3$variable3 [1] 0.1 0.1 0.1 0.1 $list3$variable4 [1] TRUE> myfunction(list1=data.frame(a=1:2, b=c('x','y')))$list1 a b 1 1 x 2 2 y $list2 $list2$variable1 [1] "variable1" $list2$variable2 [1] "variable2" $list2$variable3 [1] "variable3" $list3 $list3$variable1 [1] "character" $list3$variable2 [1] 24 $list3$variable3 [1] 0.1 0.1 0.1 0.1 $list3$variable4 [1] TRUE What you put in is what you get out. I don't know that I would deal with this the way Barry did. I would probably write code to examine the structure of what the user supplies, compare it to the required structure, and then fill in. myf <- function(l1, l2, l3) { if (missing(l1)) { ## user did not supply l1, so set it = to the default l1 <- list(v1=1, v2=2, v3=3) } else if (!is.list(l1)) { ## user must supply a list, if not, it's an error stop('l1 must be a list') } else { ## user has at least supplied a list ## now write code to check the names of the list that the user supplied ## make sure the names that the user supplied are valid, if not, stop() ## if the user supplied too few elements, fill in the missing ones ## if the user supplied too many elements stop() ## if the user supplied all the correct elements, with all the correct names, use what the user supplied } Looks complicated; maybe Barry's way is better... -Don At 5:56 PM -0500 2/26/10, Shang Gao 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. 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))} > >By definition, the values associated with each variable in the lists >would be the default unless the user impute a different value while >executing the function. But a problem arises when a variable in the >list is left out completely (not imputed at all). An example is >shown below: > >myfunction( list1=list (variable1=1, > variable2=2), #variable 3 deliberately left out > > list2=list (variable1="variable1", > variable3="position changed", > variable2="variable2"), > > list3=list (variable1="character", > variable2=24, > variable4=FALSE)) #variable 3 deliberately left out > >#The outcome of the above execution is shown below: > >$list1 >$list1$variable1 >[1] 1 > >$list1$variable2 >[1] 2 >#list1$variable3 is missing. Defaults in function not assigned in >this execution > >$list2 >$list2$variable1 >[1] "variable1" > >$list2$variable3 >[1] "position changed" > >$list2$variable2 >[1] "variable2" > > >$list3 >$list3$variable1 >[1] "character" > >$list3$variable2 >[1] 24 > >$list3$variable4 >[1] FALSE >#list3$variable3 is missing. Defaults in function not assigned in >this execution > >We later realized that the problem lies in list() commands. Hence, >we tried to enforce the defaults on the list using these codes in >the function definition: > >myfunction.alternative=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)) >{ >defaults=vector("list", 3) >names(defaults)=c("list1","list2","list3") >defaults$list1=list(variable1=1, > variable2=2, > variable3=3) >defaults$list2=list(variable1="variable1", > variable2="variable2", > variable3="variable3") >defaults$list3=list (variable1="character", > variable2=24, > variable3=c(0.1,0.1,0.1,0.1), > variable4=TRUE) >if(length(list1$variable1)==0){list1$variable1=defaults$list1$variable1} >if(length(list1$variable2)==0){list1$variable2=defaults$list1$variable2} >if(length(list1$variable3)==0){list1$variable3=defaults$list1$variable3} > >if(length(list2$variable1)==0){list2$variable1=defaults$list2$variable1} >if(length(list2$variable2)==0){list2$variable2=defaults$list2$variable2} >if(length(list2$variable3)==0){list2$variable3=defaults$list2$variable3} > >if(length(list3$variable1)==0){list3$variable1=defaults$list3$variable1} >if(length(list3$variable2)==0){list3$variable2=defaults$list3$variable2} >if(length(list3$variable3)==0){list3$variable3=defaults$list3$variable3} >if(length(list3$variable4)==0){list3$variable4=defaults$list3$variable4} > >return(list(list1=list1,list2=list2,list3=list3))} > >The outcome of execution the above function with the same commands >produces the results that we wanted: >> myfunction.alternative( list1=list (variable1=1, >+ variable2=2), #variable 3 deliberately left out >+ >+ list2=list (variable1="variable1", >+ variable3="position changed", >+ variable2="variable2"), >+ >+ list3=list (variable1="character", >+ variable2=24, >+ variable4=FALSE)) #variable 3 deliberately left out >$list1 >$list1$variable1 >[1] 1 > >$list1$variable2 >[1] 2 > >$list1$variable3 >[1] 3 > #list1$variable3 is assigned default despite being left out in the >execution command > > >$list2 >$list2$variable1 >[1] "variable1" > >$list2$variable3 >[1] "position changed" > >$list2$variable2 >[1] "variable2" > > >$list3 >$list3$variable1 >[1] "character" > >$list3$variable2 >[1] 24 > >$list3$variable4 >[1] FALSE > >$list3$variable3 >[1] 0.1 0.1 0.1 0.1 > #list3$variable3 is assigned default despite being left out in the >execution command > >Even though the function works, as you can see, the codes that >enforce the defaults are very long and bulky. Such lengthy codes >won't be efficient if we have a write a function containing a large >number of lists. We tried to come up with ideas to try to shorten >the codes, but so far none of them prove to be effective. > >What would be your recommendation to deal with such situation? It >would be great if you would be able to help us our with this >problem. We appreciate your help tremendously. > >Thank you. > >Sincerely, >Shang > > > [[alternative HTML version deleted]] > >______________________________________________ >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.-- -------------------------------------- Don MacQueen Environmental Protection Department Lawrence Livermore National Laboratory Livermore, CA, USA 925-423-1062
Hi, I think I would follow this approach too, using updatelist() from the reshape package, updatelist <- function (x, y) { common <- intersect(names(x), names(y)) x[common] <- y[common] x } myfunction=function(list1=NULL, list2=NULL, list3=NULL){ list1=updatelist(list(variable1=1, variable2=2, variable3=3), list1) list2=updatelist(list(variable1="variable1", variable2="variable2", variable3="variable3"), list2) list3=updatelist(list(variable1="character", variable2=24, variable3=c(0.1,0.1,0.1,0.1), variable4=TRUE), list3) return(list(list1=list1,list2=list2,list3=list3)) } Best regards, baptiste On 27 February 2010 01:51, Don MacQueen <macq at llnl.gov> wrote:> Barry explained your first puzzle, but let ?me add some explanation and > examples. > > >> ?tmpfun <- function( a =3 ) {a} >> ?tmpfun() > > [1] 3 >> >> ?tmpfun(a='x') > > [1] "x" > > Inside the function, the value of the argument is whatever the user > supplied. The default is replaced by what the user supplies. There is no > mechanism for retaining the default structure and filling in any missing > parts. R never preserves the defaults when the user supplies something other > than the default. > > For example, and using your function, > >> ?myfunction(list1='x') > > $list1 > [1] "x" > > $list2 > $list2$variable1 > [1] "variable1" > > $list2$variable2 > [1] "variable2" > > $list2$variable3 > [1] "variable3" > > > $list3 > $list3$variable1 > [1] "character" > > $list3$variable2 > [1] 24 > > $list3$variable3 > [1] 0.1 0.1 0.1 0.1 > > $list3$variable4 > [1] TRUE > > >> ?myfunction(list1=data.frame(a=1:2, b=c('x','y'))) > > $list1 > ?a b > 1 1 x > 2 2 y > > $list2 > $list2$variable1 > [1] "variable1" > > $list2$variable2 > [1] "variable2" > > $list2$variable3 > [1] "variable3" > > > $list3 > $list3$variable1 > [1] "character" > > $list3$variable2 > [1] 24 > > $list3$variable3 > [1] 0.1 0.1 0.1 0.1 > > $list3$variable4 > [1] TRUE > > What you put in is what you get out. > > I don't know that I would deal with this the way Barry did. I would probably > write code to examine the structure of what the user supplies, compare it to > the required structure, and then fill in. > > myf <- function(l1, l2, l3) { > ?if (missing(l1)) { > ? ## user did not supply l1, so set it = to the default > ? ?l1 <- list(v1=1, v2=2, v3=3) > ?} ?else if (!is.list(l1)) { > ? ## user must supply a list, if not, it's an error > ? stop('l1 must be a list') > } else { > ? ## user has at least supplied a list > ? ## now write code to check the names of the list that the user supplied > ? ## make sure the names that the user supplied are valid, if not, stop() > ? ## if the user supplied too few elements, fill in the missing ones > ? ## if the user supplied too many elements stop() > ? ## if the user supplied all the correct elements, with all the correct > names, use what the user supplied > } > > Looks complicated; maybe Barry's way is better... > > -Don > > At 5:56 PM -0500 2/26/10, Shang Gao 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. 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))} >> >> By definition, the values associated with each variable in the lists would >> be the default unless the user impute a different value while executing the >> function. But a problem arises when a variable in the list is left out >> completely (not imputed at all). An example is shown below: >> >> myfunction( list1=list ?(variable1=1, >> ? ? ? ? ? ? ? ? ? ? ? ?variable2=2), #variable 3 deliberately left out >> >> ? ? ? ? ? ?list2=list ?(variable1="variable1", >> ? ? ? ? ? ? ? ? ? ? ? ?variable3="position changed", >> ? ? ? ? ? ? ? ? ? ? ? ?variable2="variable2"), >> >> ? ? ? ? ? ?list3=list ?(variable1="character", >> ? ? ? ? ? ? ? ? ? ? ? ?variable2=24, >> ? ? ? ? ? ? ? ? ? ? ? ?variable4=FALSE)) #variable 3 deliberately left out >> >> #The outcome of the above execution is shown below: >> >> $list1 >> $list1$variable1 >> [1] 1 >> >> $list1$variable2 >> [1] 2 >> #list1$variable3 is missing. Defaults in function not assigned in this >> execution >> >> $list2 >> $list2$variable1 >> [1] "variable1" >> >> $list2$variable3 >> [1] "position changed" >> >> $list2$variable2 >> [1] "variable2" >> >> >> $list3 >> $list3$variable1 >> [1] "character" >> >> $list3$variable2 >> [1] 24 >> >> $list3$variable4 >> [1] FALSE >> #list3$variable3 is missing. Defaults in function not assigned in this >> execution >> >> We later realized that the problem lies in list() commands. Hence, we >> tried to enforce the defaults on the list using these codes in the function >> definition: >> >> myfunction.alternative=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)) >> { >> defaults=vector("list", 3) >> names(defaults)=c("list1","list2","list3") >> defaults$list1=list(variable1=1, >> ? ? ? ? ? ? ? ?variable2=2, >> ? ? ? ? ? ? ? ?variable3=3) >> defaults$list2=list(variable1="variable1", >> ? ? ? ? ? ? ? ?variable2="variable2", >> ? ? ? ? ? ? ? ?variable3="variable3") >> defaults$list3=list ?(variable1="character", >> ? ? ? ? ? ? ? ?variable2=24, >> ? ? ? ? ? ? ? ?variable3=c(0.1,0.1,0.1,0.1), >> ? ? ? ? ? ? ? ?variable4=TRUE) >> if(length(list1$variable1)==0){list1$variable1=defaults$list1$variable1} >> if(length(list1$variable2)==0){list1$variable2=defaults$list1$variable2} >> if(length(list1$variable3)==0){list1$variable3=defaults$list1$variable3} >> >> if(length(list2$variable1)==0){list2$variable1=defaults$list2$variable1} >> if(length(list2$variable2)==0){list2$variable2=defaults$list2$variable2} >> if(length(list2$variable3)==0){list2$variable3=defaults$list2$variable3} >> >> if(length(list3$variable1)==0){list3$variable1=defaults$list3$variable1} >> if(length(list3$variable2)==0){list3$variable2=defaults$list3$variable2} >> if(length(list3$variable3)==0){list3$variable3=defaults$list3$variable3} >> if(length(list3$variable4)==0){list3$variable4=defaults$list3$variable4} >> >> return(list(list1=list1,list2=list2,list3=list3))} >> >> The outcome of execution the above function with the same commands >> produces the results that we wanted: >>> >>> ?myfunction.alternative( list1=list ?(variable1=1, >> >> + ? ? ? ? ? ? ? ? ? ? ? ? variable2=2), #variable 3 deliberately left out >> + >> + ? ? ? ? ? ? list2=list ?(variable1="variable1", >> + ? ? ? ? ? ? ? ? ? ? ? ? variable3="position changed", >> + ? ? ? ? ? ? ? ? ? ? ? ? variable2="variable2"), >> + >> + ? ? ? ? ? ? list3=list ?(variable1="character", >> + ? ? ? ? ? ? ? ? ? ? ? ? variable2=24, >> + ? ? ? ? ? ? ? ? ? ? ? ? variable4=FALSE)) #variable 3 deliberately left >> out >> $list1 >> $list1$variable1 >> [1] 1 >> >> $list1$variable2 >> [1] 2 >> >> $list1$variable3 >> [1] 3 >> ?#list1$variable3 is assigned default despite being left out in the >> execution command >> >> >> $list2 >> $list2$variable1 >> [1] "variable1" >> >> $list2$variable3 >> [1] "position changed" >> >> $list2$variable2 >> [1] "variable2" >> >> >> $list3 >> $list3$variable1 >> [1] "character" >> >> $list3$variable2 >> [1] 24 >> >> $list3$variable4 >> [1] FALSE >> >> $list3$variable3 >> [1] 0.1 0.1 0.1 0.1 >> ?#list3$variable3 is assigned default despite being left out in the >> execution command >> >> Even though the function works, as you can see, the codes that enforce the >> defaults are very long and bulky. Such lengthy codes won't be efficient if >> we have a write a function containing a large number of lists. We tried to >> come up with ideas to try to shorten the codes, but so far none of them >> prove to be effective. >> >> What would be your recommendation to deal with such situation? It would be >> great if you would be able to help us our with this problem. We appreciate >> your help tremendously. >> >> Thank you. >> >> Sincerely, >> Shang >> >> >> ? ? ? ?[[alternative HTML version deleted]] >> >> ______________________________________________ >> 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. > > > -- > -------------------------------------- > Don MacQueen > Environmental Protection Department > Lawrence Livermore National Laboratory > Livermore, CA, USA > 925-423-1062 > > ______________________________________________ > 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. >