approx<-function (x, y, xout, method = "linear", n = 50, rule = 1, f = 0)
{
	if (!is.numeric(x) || !is.numeric(y))
		stop("approx: x and y must be numeric")
	nx <- length(x)
	if (nx != length(y))
		stop("x and y must have equal lengths")
	if (nx < 2)
		stop("approx requires at least two values to interpolate")
	method <- pmatch(method, c("linear", "constant"))
	if (is.na(method))
		stop("approx: invalid interpolation method")
	ok <- !(is.na(x) | is.na(y))
	x <- x[ok]
	y <- y[ok]
	o <- order(x)
	x <- x[o]
	y <- y[o]
	if (missing(xout)) {
		if (n <= 0)
			stop("approx requires n >= 1")
		xout <- seq(x[1], x[nx], length = n)
	}
	switch(method,
	{ #-- 1 ---
		if (rule == 1) {
			low <- y[1]
			high <- y[nx]
			na.ok<-FALSE
		} else if (rule == 2) {
			low <- as.double(NA)
			high <- low
			na.ok<-TRUE
		} else stop("invalid extrapolation rule in approx")
		y <- .C("approx", as.double(x), as.double(y),
			nx, xout = as.double(xout), length(xout),
			low, high, NAOK=na.ok)$xout
		},
		{ #-- 2 -- step function approximation

		yleft  <- sapply(xout, function(xi) y[max((1:nx)[xi >= x])])
		yright <- sapply(xout, function(xi) y[min((1:nx)[xi <= x])])
		if (rule == 1) {
			yleft[is.na(yleft)] <- y[1]
			yright[is.na(yright)] <- y[nx]
		}
		y <- yleft * f + yright * (1 - f)
		})
	list(x = xout, y = y)
}
