As I've mentioned a number of times. I find it very useful to have lowess()
become a generic function so that a lowess.formula() can be defined.
Below is a patch that makes both changes, as well as updating the
corresponding help documentation.
Gregory R. Warnes
Manager, Non-Clinical Statistics
Pfizer Global Research and Development
Tel: 860-715-3536
? DESCRIPTION
? Makefile
? lowess.generic.patch
? R/mean.R
? man/logLik.glm.Rd
? man/logLik.lm.Rd
? man/mean.Rd
? src/Makefile
Index: R/lowess.R
===================================================================
RCS file: /cvs/R/src/library/stats/R/lowess.R,v
retrieving revision 1.1
diff -u -r1.1 lowess.R
--- R/lowess.R 2003/12/09 07:24:23 1.1
+++ R/lowess.R 2004/01/21 06:42:58
@@ -1,4 +1,10 @@
-lowess <- function(x, y=NULL, f=2/3, iter=3,
delta=.01*diff(range(xy$x[o]))) {
+
+
+lowess <- function(x,...)
+ UseMethod("lowess")
+
+lowess.default <-
+function(x, y=NULL, f=2/3, iter=3, delta=.01*diff(range(xy$x[o]))) {
xy <- xy.coords(x,y)
n <- length(xy$x)
if(n == 0) stop("x is empty")
@@ -14,3 +20,25 @@
double(n),
double(n), PACKAGE="base")[c("x","y")]
}
+
+
+
+"lowess.formula" <- function (formula,
+ data = parent.frame(), subset, na.action,
+ f=2/3, iter=3,
+ delta=.01*diff(range(mf[-response])), ... )
+{
+ if (missing(formula) || (length(formula) != 3))
+ stop("formula missing or incorrect")
+ if (missing(na.action))
+ na.action <- getOption("na.action")
+ m <- match.call(expand.dots = FALSE)
+ if (is.matrix(eval(m$data, parent.frame())))
+ m$data <- as.data.frame(data)
+ m$... <- m$f <- m$iter <- m$delta <- NULL
+ m[[1]] <- as.name("model.frame")
+ mf <- eval(m, parent.frame())
+ response <- attr(attr(mf, "terms"), "response")
+ lowess.default(mf[[-response]], mf[[response]], f=f, iter=iter,
delta=delta)
+}
+
Index: man/lowess.Rd
===================================================================
RCS file: /cvs/R/src/library/stats/man/lowess.Rd,v
retrieving revision 1.2
diff -u -r1.2 lowess.Rd
--- man/lowess.Rd 2003/12/09 18:32:33 1.2
+++ man/lowess.Rd 2004/01/21 06:44:18
@@ -1,10 +1,23 @@
\name{lowess}
+\alias{lowess}
+\alias{lowess.default}
+\alias{lowess.formula}
\title{Scatter Plot Smoothing}
\usage{
-lowess(x, y = NULL, f = 2/3, iter=3, delta = 0.01 * diff(range(xy$x[o])))
+lowess(x, ...)
+\method{lowess}{default}(x, y = NULL, f = 2/3, iter = 3, delta = 0.01 *
+ diff(range(xy$x[o])), ...)
+\method{lowess}{formula}(formula,data = parent.frame(), subset, na.action,
+ f=2/3, iter=3, delta=.01*diff(range(mf[-response])), ... )
}
-\alias{lowess}
\arguments{
+ \item{formula}{ formula providing a single dependent variable (y) and
+ an single independent variable (x) to use as coordinates in the
+ scatter plot.}
+ \item{data}{a data.frame (or list) from which the variables in `formula'
+ should be taken.}
+ \item{subset}{ an optional vector specifying a subset of observations to
be
+ used in the fitting process. }
\item{x, y}{vectors giving the coordinates of the points in the scatter
plot.
Alternatively a single plotting structure can be specified.}
\item{f}{the smoother span. This gives the proportion of points in
@@ -16,6 +29,11 @@
\item{delta}{values of \code{x} which lie within \code{delta}
of each other are replaced by a single value in the output from
\code{lowess}. Defaults to 1/100th of the range of \code{x}.}
+ \item{na.action}{a function which indicates what should happen when the
data
+ contain `NA's. The default is set by the `na.action' setting
+ of `options', and is `na.fail' if that is unset. The
+ ``factory-fresh'' default is `na.omit'.}
+ \item{...}{parameters for methods.}
}
\description{
This function performs the computations for the
@@ -43,9 +61,17 @@
}
\examples{
data(cars)
+
+# default method
plot(cars, main = "lowess(cars)")
lines(lowess(cars), col = 2)
lines(lowess(cars, f=.2), col = 3)
+legend(5, 120, c(paste("f = ", c("2/3", ".2"))), lty = 1, col = 2:3)
+
+# formula method
+plot(dist ~ speed, data=cars, main = "lowess(cars)")
+lines(lowess(dist ~ speed, data=cars), col = 2)
+lines(lowess(dist ~ speed, data=cars, f=.2), col = 3)
legend(5, 120, c(paste("f = ", c("2/3", ".2"))), lty = 1, col = 2:3)
}
\keyword{smooth}
LEGAL NOTICE\ Unless expressly stated otherwise, this messag...{{dropped}}
Please make lowess() generic (was: Reorganization of packages in the R distribution)
4 messages · Warnes, Gregory R, Martin Maechler, Brian Ripley +1 more
"Greg" == Warnes, Gregory R <gregory_r_warnes@groton.pfizer.com>
on Wed, 21 Jan 2004 01:48:15 -0500 writes:
Greg> As I've mentioned a number of times. I find it very
Greg> useful to have lowess() become a generic function so
Greg> that a lowess.formula() can be defined.
Greg> Below is a patch that makes both changes, as well as
Greg> updating the corresponding help documentation.
I think most times you mentioned this, Brian told you that
"loess" was there and was generic and was to be recommended over
lowess anyway.
Hence I think we should hear reasons why lowess is to be
preferred to loess in some cases.
[and I think I may well support your argument; I've forgotten
which reasons I thought to have in the past when deciding for
lowess (against loess).]
*Not* making lowess generic is one way to recommend loess ;-)
Martin
On Wed, 21 Jan 2004, Martin Maechler wrote:
"Greg" == Warnes, Gregory R <gregory_r_warnes@groton.pfizer.com>
on Wed, 21 Jan 2004 01:48:15 -0500 writes:
Greg> As I've mentioned a number of times. I find it very
Greg> useful to have lowess() become a generic function so
Greg> that a lowess.formula() can be defined.
Greg> Below is a patch that makes both changes, as well as
Greg> updating the corresponding help documentation.
I think most times you mentioned this, Brian told you that
"loess" was there and was generic and was to be recommended over
lowess anyway.
Not quite: loess() is not generic, but it does have a formula interface and it was recommended over lowess() by the authors of both. (loess() is not generic for the reasons I sketch below.)
Hence I think we should hear reasons why lowess is to be preferred to loess in some cases. [and I think I may well support your argument; I've forgotten which reasons I thought to have in the past when deciding for lowess (against loess).] *Not* making lowess generic is one way to recommend loess ;-)
It seems to me only to be worth making functions generic if they are likely to be extended in unforeseen ways: making image() generic was one of those. For lowess, the only plausible methods are for formula and vector, so why not just write a wrapper called lowessForm? I took the same approach when re-implementing loess: it could have had a matrix + vector interface but it did not seem worth setting up a generic just for that.
Brian D. Ripley, ripley@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
Prof Brian Ripley <ripley@stats.ox.ac.uk> writes:
On Wed, 21 Jan 2004, Martin Maechler wrote:
"Greg" == Warnes, Gregory R <gregory_r_warnes@groton.pfizer.com>
on Wed, 21 Jan 2004 01:48:15 -0500 writes:
Greg> As I've mentioned a number of times. I find it very
Greg> useful to have lowess() become a generic function so
Greg> that a lowess.formula() can be defined.
Greg> Below is a patch that makes both changes, as well as
Greg> updating the corresponding help documentation.
I think most times you mentioned this, Brian told you that
"loess" was there and was generic and was to be recommended over
lowess anyway.
Not quite: loess() is not generic, but it does have a formula interface and it was recommended over lowess() by the authors of both. (loess() is not generic for the reasons I sketch below.)
Not to mention that "lowess" is a speling misteak! http://www.museum.state.il.us/exhibits/larson/loess.html
O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907