Or use modifyList which is in the core of R. On Sat, Feb 27, 2010 at 5:22 AM, baptiste auguie <baptiste.aug...@googlemail.com> wrote: > 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 <m...@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@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@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. >> > > ______________________________________________ > R-help@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. >
______________________________________________ R-help@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.