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.