Dear all,

perhaps I am using princomp.formula and prcomp.formula in a way that
is not documented to work, but then the documentation just says:

        formula: a formula with no response variable.

Thus, to avoid a lot of typing, it would be nice if one could use '.'
and '-' in the formula, e.g.

> library(DAAG)
> res <- prcomp(~ . - case - site - Pop - sex, possum)
Error in prcomp.formula(~. - case - site - Pop - sex, possum) : 
        PCA applies only to numerical variables
> res <- princomp(~ . - case - site - Pop - sex, possum)
Error in princomp.formula(~. - case - site - Pop - sex, possum) : 
        PCA applies only to numerical variables

Unfortunately, as the examples above show, this is currently not
possible, since both functions test whether any term mentioned in the
formula is non numeric or a factor, instead of just testing those that
enter the analysis.

The attached patch should allow the use of '.' and '-', while still
producing an error when a factor or a non-numeric variable is
specified to enter the analysis:

> library(DAAG)
> res <- prcomp(~ . - case - site - Pop - sex, possum)
> res <- princomp(~ . - case - site - Pop - sex, possum)
> res <- prcomp(~ . - case - site - Pop, possum)
Error in prcomp.formula(~. - case - site - Pop, possum) : 
        PCA applies only to numerical variables
> res <- princomp(~ . - case - site - Pop, possum)
Error in princomp.formula(~. - case - site - Pop, possum) : 
        PCA applies only to numerical variables

On my machine, `make check FORCE=FORCE' succeeds with this patch and,
as far as I can tell, no modification of the help pages would be
necessary.  

Cheers,

        Berwin

Index: src/library/stats/R/princomp.R
===================================================================
--- src/library/stats/R/princomp.R      (revision 37571)
+++ src/library/stats/R/princomp.R      (working copy)
@@ -10,13 +10,14 @@
     mf$... <- NULL
     mf[[1]] <- as.name("model.frame")
     mf <- eval.parent(mf)
+    na.act <- attr(mf, "na.action")
+    mt <- attr(mf, "terms") # allow model.frame to update it
+    attr(mt, "intercept") <- 0
+    mterms <- attr(mt, "term.labels")
     ## this is not a `standard' model-fitting function,
     ## so no need to consider contrasts or levels
-    if(any(sapply(mf, function(x) is.factor(x) || !is.numeric(x))))
+    if(any(sapply(mterms, function(x) is.factor(mf[,x]) || 
!is.numeric(mf[,x]))))
         stop("PCA applies only to numerical variables")
-    na.act <- attr(mf, "na.action")
-    mt <- attr(mf, "terms") # allow model.frame to update it
-    attr(mt, "intercept") <- 0
     x <- model.matrix(mt, mf)
     res <- princomp.default(x, ...)
     ## fix up call to refer to the generic, but leave arg name as `formula'
Index: src/library/stats/R/prcomp.R
===================================================================
--- src/library/stats/R/prcomp.R        (revision 37571)
+++ src/library/stats/R/prcomp.R        (working copy)
@@ -37,13 +37,14 @@
     mf$... <- NULL
     mf[[1]] <- as.name("model.frame")
     mf <- eval.parent(mf)
+    na.act <- attr(mf, "na.action")
+    mt <- attr(mf, "terms")
+    attr(mt, "intercept") <- 0
+    mterms <- attr(mt, "term.labels")
     ## this is not a `standard' model-fitting function,
     ## so no need to consider contrasts or levels
-    if (any(sapply(mf, function(x) is.factor(x) || !is.numeric(x))))
+    if(any(sapply(mterms, function(x) is.factor(mf[,x]) || 
!is.numeric(mf[,x]))))
         stop("PCA applies only to numerical variables")
-    na.act <- attr(mf, "na.action")
-    mt <- attr(mf, "terms")
-    attr(mt, "intercept") <- 0
     x <- model.matrix(mt, mf)
     res <- prcomp.default(x, ...)
     ## fix up call to refer to the generic, but leave arg name as `formula'
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to