Dear R gurus, I have a function "goftests" that receives the following arguments: * a vector "x" of data values; * a distribution name "dist"; * the dots list ("...") containing a list a parameters to pass to CDF function; and calls several goodness-of-fit tests on the given data values against the given distribution. That is: ##### BEGIN CODE SNIP ##### # Covert a distribution name to the related CDF function name distname2cdfname <- function( dist ) { if ( dist == "beta" ) { return( "pbeta" ); } if ( dist == "cauchy" ) { return( "pcauchy" ); } # many other and personalized (e.g. pareto, ...) distributions ... return( "" ); # fall-back case } # Performs some GoF tests (KS, Chi-Square, Anderson-Darling,...) # (the "..." list contains parameters for CDF function) goftests <- function( x, dist, ... ) { cdfname <- distname2cdfname( dist ); res$ks <- ks.test( x, cdfname, ... ); # res$chisq <- ... # res$anddarl <- ... return( res ) }; ##### END CODE SNIP ##### So the problem is passing "..." to CDF function (for instance, see ks.test above) in the "right form". The "..." is passed (to "goftests") as a list object and it should be converted to an "argument list". For instance: ##### BEGIN CODE SNIP ##### parms <- list( shape1 = 2, shape2 = 5 ); goftests( x, "beta", parms[["shape1"]], parms[["shape2"]] ); # Works! goftests( x, "beta", parms ) # Don't Works! parms <- list( aNum = 5, aVector = c(1,2,3), aMatrix = matrix(c(4,5,6,7,8,9),nrow=2,byrow=T) ); goftests( x, "my-special-distr", parms[["aVector"]], parms[["aMatrix"]], parms[["aNumber"]] ); # Works! goftests( x, "my-special-distr", parms ) # Don't Works! ##### END CODE SNIP ##### Obviously I have to use the "don't work" form. How can I do this in R (if possible)? Thank you very much in advance! Best regards, -- Marco
hadley wickham
2007-Mar-03 15:05 UTC
[R] How to convert List object to function arguments?
Have a look at do.call Hadley On 3/3/07, Shiazy <shiazy at gmail.com> wrote:> Dear R gurus, > > I have a function "goftests" that receives the following arguments: > * a vector "x" of data values; > * a distribution name "dist"; > * the dots list ("...") containing a list a parameters to pass to CDF > function; > and calls several goodness-of-fit tests on the given data values against > the given distribution. > That is: > > ##### BEGIN CODE SNIP ##### > > # Covert a distribution name to the related CDF function name > distname2cdfname <- function( dist ) > { > if ( dist == "beta" ) { return( "pbeta" ); } > if ( dist == "cauchy" ) { return( "pcauchy" ); } > > # many other and personalized (e.g. pareto, ...) distributions ... > > return( "" ); # fall-back case > } > > # Performs some GoF tests (KS, Chi-Square, Anderson-Darling,...) > # (the "..." list contains parameters for CDF function) > goftests <- function( x, dist, ... ) > { > cdfname <- distname2cdfname( dist ); > res$ks <- ks.test( x, cdfname, ... ); > # res$chisq <- ... > # res$anddarl <- ... > > return( res ) > }; > > ##### END CODE SNIP ##### > > So the problem is passing "..." to CDF function (for instance, see > ks.test above) in the "right form". The "..." is passed (to "goftests") > as a list object and it should be converted to an "argument list". > For instance: > > ##### BEGIN CODE SNIP ##### > > parms <- list( shape1 = 2, shape2 = 5 ); > goftests( x, "beta", parms[["shape1"]], parms[["shape2"]] ); # Works! > goftests( x, "beta", parms ) # Don't Works! > > parms <- list( aNum = 5, aVector = c(1,2,3), aMatrix > matrix(c(4,5,6,7,8,9),nrow=2,byrow=T) ); > goftests( x, "my-special-distr", parms[["aVector"]], parms[["aMatrix"]], > parms[["aNumber"]] ); # Works! > goftests( x, "my-special-distr", parms ) # Don't Works! > > ##### END CODE SNIP ##### > > Obviously I have to use the "don't work" form. > > How can I do this in R (if possible)? > > Thank you very much in advance! > > Best regards, > > -- Marco > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >
With a little change it's seem to work: x <- c(0, 1855, 72, 4830, 493, 424, 193, 2489, 156262, 4557, 958) params <- list(shape2=5, shape1=2) do.call( "ks.test", c(list(x), cdfname( "beta" ), params )) In fact if I do call("ks.test", list(x=x, cdfname=cdfname, ...)) I get: ks.test(list(x = c(0, 1855, 72, 4830, 493, 424, 193, 2489, 156262, 4557, 958), y = "pbeta", list(shape2 = 5, shape1 = 2))) and the error: Error in y(sort(x), ...) : argument "shape2" is missing, with no default Instead with the new form: call( "ks.test", c(list(x), mg_dists_cdfName( "beta" ), parms )) I get: ks.test(list(c(0, 1855, 72, 4830, 493, 424, 193, 2489, 156262, 4557, 958), "pbeta", shape2 = 5, shape1 = 2)) and no error. Thank you so much!!! -- Marco hadley wickham wrote:> On 3/3/07, Shiazy <shiazy at gmail.com> wrote: >> "do.call" createa a function call and evaluates it. I think this isn't >> for me. Same thing for "call"; it wants the function name as first >> argument. >> >> However, I have to pass to "ks.test" the CDF function name and, >> separately, the related arguments. >> >> ks.test( x, cdfname, ... ); >> >> The problem is "..." comes as a list object and I didn't find a way to >> "coerce" this object to a arguments list, preserving names a values >> (note each list item can be a complex object such as a vector, matrix, >> ... so I cannot use unlist o as.array) > > I think > do.call("ks.test", list(x=x, cdfname=cdfname, ...)) > will do what you want. > > Hadley > > PS. You don't need ; at the end of every line. >
Patrick Burns wrote:> You might have found 'do.call' in S Poetry. >I've taken a look just now. Thank you so much! -- Marco> Patrick Burns > patrick at burns-stat.com > +44 (0)20 8525 0696 > http://www.burns-stat.com > (home of S Poetry and "A Guide for the Unwilling S User") > > Shiazy wrote: > >> Dear R gurus, >> >> I have a function "goftests" that receives the following arguments: >> * a vector "x" of data values; >> * a distribution name "dist"; >> * the dots list ("...") containing a list a parameters to pass to CDF >> function; >> and calls several goodness-of-fit tests on the given data values >> against the given distribution. >> That is: >> >> ##### BEGIN CODE SNIP ##### >> >> # Covert a distribution name to the related CDF function name >> distname2cdfname <- function( dist ) >> { >> if ( dist == "beta" ) { return( "pbeta" ); } >> if ( dist == "cauchy" ) { return( "pcauchy" ); } >> >> # many other and personalized (e.g. pareto, ...) distributions ... >> >> return( "" ); # fall-back case >> } >> >> # Performs some GoF tests (KS, Chi-Square, Anderson-Darling,...) >> # (the "..." list contains parameters for CDF function) >> goftests <- function( x, dist, ... ) >> { >> cdfname <- distname2cdfname( dist ); >> res$ks <- ks.test( x, cdfname, ... ); >> # res$chisq <- ... >> # res$anddarl <- ... >> >> return( res ) >> }; >> >> ##### END CODE SNIP ##### >> >> So the problem is passing "..." to CDF function (for instance, see >> ks.test above) in the "right form". The "..." is passed (to >> "goftests") as a list object and it should be converted to an >> "argument list". >> For instance: >> >> ##### BEGIN CODE SNIP ##### >> >> parms <- list( shape1 = 2, shape2 = 5 ); >> goftests( x, "beta", parms[["shape1"]], parms[["shape2"]] ); # Works! >> goftests( x, "beta", parms ) # Don't Works! >> >> parms <- list( aNum = 5, aVector = c(1,2,3), aMatrix = >> matrix(c(4,5,6,7,8,9),nrow=2,byrow=T) ); >> goftests( x, "my-special-distr", parms[["aVector"]], >> parms[["aMatrix"]], parms[["aNumber"]] ); # Works! >> goftests( x, "my-special-distr", parms ) # Don't Works! >> >> ##### END CODE SNIP ##### >> >> Obviously I have to use the "don't work" form. >> >> How can I do this in R (if possible)? >> >> Thank you very much in advance! >> >> Best regards, >> >> -- Marco >> >> ______________________________________________ >> R-help at stat.math.ethz.ch 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. >> >> >> >> >