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. >> >> >> >> >