# Why does expressing one function
require(ctest)
t.test
# return only
function (x, ...)
UseMethod("t.test")
<environment: namespace:ctest>
# but expressing another function
shapiro.test
# returns more complete code?
function (x)
{
DNAME <- deparse(substitute(x))
x <- sort(x[complete.cases(x)])
n <- length(x)
if (n < 3 || n > 5000)
stop("sample size must be between 3 and 5000")
rng <- x[n] - x[1]
if (rng == 0)
stop("all `x[]' are identical")
if (rng < 1e-10)
x <- x/rng
n2 <- n%/%2
sw <- .C("swilk", init = FALSE, as.single(x), n, n1 =
as.integer(n),
as.integer(n2), a = single(n2), w = double(1), pw = double(1),
ifault = integer(1), PACKAGE = "ctest")
if (sw$ifault && sw$ifault != 7)
stop(paste("ifault=", sw$ifault, ". This should not
happen"))
RVAL <- list(statistic = c(W = sw$w), p.value = sw$pw, method =
"Shapiro-Wilk normality test",
data.name = DNAME)
class(RVAL) <- "htest"
return(RVAL)
}
<environment: namespace:ctest>
--
Richard E. Remington III
Statistician
KERN Statistical Services, Inc.
PO Box 1046
Boise, ID 83701
Tel: 208.426.0113
KernStat.com
On Tue, 9 Dec 2003, Remington, Richard wrote:> # Why does expressing one function > > require(ctest) > t.test > > # return only > > function (x, ...) > UseMethod("t.test") > <environment: namespace:ctest> > > # but expressing another function > > shapiro.test > > # returns more complete code?[...] False hypothesis: both are the complete code. You are not understanding (S3-style) generic functions: see any good book on R/S. (`An Introduction to R' is based on notes that predate them, but they are covered in more detail in the draft R Language manual. `The reader is referred to the official references for a complete discussion of this mechanism.' which I think means Chambers & Hastie, 1992,) -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Remington, Richard wrote:> # Why does expressing one function > > require(ctest) > t.test > > # return only > > function (x, ...) > UseMethod("t.test") > <environment: namespace:ctest> > > # but expressing another function > > shapiro.test > > # returns more complete code? > > function (x) > { > DNAME <- deparse(substitute(x)) > x <- sort(x[complete.cases(x)]) > n <- length(x) > if (n < 3 || n > 5000) > stop("sample size must be between 3 and 5000")... Short answer: Unless you're programming your own functions, you don't need to worry about that. Long answer: Because the first is generic - it looks at what kind of data you're testing (two vectors, a formula, whatever, ...) and calls the appropriate sub-function. shapiro.test does not; it just takes one data format, and stops in its tracks if that's not what you've provided. The ideas behind this are documented in "Writing R Extensions" (R-exts.pdf) which is supplied with binary R distributions, and is available from CRAN. See chapter 6, "Generic functions and methods", in the version that accompanies R-1.8.1. Cheers Jason -- Indigo Industrial Controls Ltd. http://www.indigoindustrial.co.nz 64-21-343-545 jasont at indigoindustrial.co.nz
Perhaps what should be added to the previous answers is that you can find out where the real work is done like this: require(ctest) t.test methods(t.test) ctest:::t.test.default ctest:::t.test.formula If the class of the first argument to t.test is formula then t.test.formula gets invoked so that's where the real work is done; otherwise, t.test.default gets invoked so that's where the real work is done. --- Remington, Richard wrote:> # Why does expressing one function > > require(ctest) > t.test > > # return only > > function (x, ...) > UseMethod("t.test") > <environment: namespace:ctest> > > # but expressing another function > > shapiro.test > > # returns more complete code? > > function (x) > { > DNAME <- deparse(substitute(x)) > x <- sort(x[complete.cases(x)]) > n <- length(x) > if (n < 3 || n > 5000) > stop("sample size must be between 3 and 5000")