Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fit 2d surface using LOESS in R

Tags:

r

I want to take noisy 2d data and use LOESS smoothing to find a smoother 2D surface. The data is the form of a data frame or matrix of r rows and c columns. The 'asbio' package will do surface plots for n*n data, and I can work out how to do 1D fits with 'loess' from the stats base package but I can't work out how to do the 2D plot.

library(rgl)


age <- 1:100
year <- 1959:2012
z<- data.frame(matrix(array(0, length(age)*length(year)),nrow=length(age), ncol=length(year)))
rownames(z) <- age
colnames(z) <- year
distYear <- dnorm(1:length(year), 26, 10)
distAge <- dnorm(age, 50, 15)
for(theYear in year){
  #for(theAge in age){
    z[,theYear-year[1]+1] <- as.numeric(distYear[theYear-year[1]+1]*distAge*runif(length(age))*50000)
  #}
}
z<- data.matrix(z)
z <- data.frame(z)
colnames(z) <- year

# First define the colours for the Z values.
zlim <- range(z)    
zlen <- zlim[2] - zlim[1] 
scale <- 20/zlen
colorlut <- terrain.colors(20,alpha=1.0) # height color lookup table
col <- colorlut[ (t(as.matrix(z))-zlim[1])*scale+1 ] # assign colors to heights for each point.


surface3d(age,year,as.matrix(z), col=col)

loess(z~age+year,data=data.frame(z))

I get an error rejecting the data.frame as being a list, but I suspect there is more to it than that. Searching for information, I can only find the 1D linear descriptions.

Can anyone help?

like image 555
Chris Martin Avatar asked Apr 29 '15 14:04

Chris Martin


1 Answers

Worked it out....

The data frame or matrix needs to be converted to a three columns data frame. Once the data frame z above is created, the following will smooth and display it (using rgl).

open3d(useFreeType=par3d("useFreeType"))
surface3d(age,year,as.matrix(z), col=col)

zz <- z 
zz$Ages <- rownames(z)
zzx <- melt(zz, id.vars="Ages", value.name="Vals")

theResult <-     loess(Vals~as.numeric(Ages)+as.numeric(variable),data=data.frame(zzz))
resultTable <- matrix(theResult$fitted, nrow=length(age), length(year))

open3d(useFreeType=par3d("useFreeType"))
surface3d(age,year,as.matrix(resultTable), col=col)
like image 166
Chris Martin Avatar answered Oct 20 '22 03:10

Chris Martin