approxfun <- function (x, y, method = "linear", rule = 1, f = 0)
{
	if (!is.numeric(x) || !is.numeric(y))
		stop("approx: x and y must be numeric")
	n <- length(x)
	if (n != length(y))
		stop("x and y must have equal lengths")
	if (n < 2)
		stop("approx requires at least two values to interpolate")
	method <- pmatch(method, c("linear", "constant"))
	if (is.na(method))
		stop("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]
	rm(o,ok) # clean up the environment
	switch(method,
	{ #-- 1 ---
		if (rule == 1) {
			low <- y[1]
			high <- y[n]
			na.ok<-FALSE
		} else if (rule == 2) {
			low <- as.double(NA)
			high <- low
			na.ok<-TRUE
		} else stop("invalid extrapolation rule in approxfun")
		rm(method, rule, f)
		function(v) .C("approx", as.double(x), as.double(y),
			       n, xout = as.double(v), length(v),
			       low, high, NAOK=na.ok)$xout
	},
	{ #-- 2 -- step function approximation
	 if (rule==1) {
		 rm(method,rule)
		 function(v) {
			 yleft	<- sapply(v,function(xi) y[max((1:n)[xi >= x])])
			 yright <- sapply(v,function(xi) y[min((1:n)[xi <= x])])
			 yleft[is.na(yleft)] <- y[1]
			 yright[is.na(yright)] <- y[n]
			 yleft * f + yright * (1 - f)
		 }
	 } else if (rule==2) {
		 rm(method,rule)
		 function(v) {
			 yleft	<- sapply(v,function(xi) y[max((1:n)[xi >= x])])
			 yright <- sapply(v,function(xi) y[min((1:n)[xi <= x])])
			 yleft * f + yright * (1 - f)
		 }
	 }
	})
}
