Chris Farmer
Chris Farmer

Reputation: 25415

How can I smooth an array in R?

I have a 2-D array in R which represents value data for a grid of rows and columns. It looks like this:

     [,1] [,2] [,3] [,4]
[1,]    1    1    2    1
[2,]    1    5    6    3
[3,]    2    3    2    1
[4,]    1    1    1    1

I want to "smooth" these values. At this proof-of-concept point, I am fine with using any popular smoothing function. I am currently attempting to use the smooth.spline function:

smooth.spline(x, y = NULL, w = NULL, df, spar = NULL,
              cv = FALSE, all.knots = FALSE, nknots = NULL,
              keep.data = TRUE, df.offset = 0, penalty = 1,
              control.spar = list())

by (naively) calling

smoothed <- smooth.spline(myarray)

When I run this, I get this error:

Error in smooth.spline(a) : need at least four unique 'x' values

My array has four or more unique values in each dimension, so I am thinking that I do not know how to properly format the input data. Can someone give me some pointers to this kind of thing? The examples for smooth-like functions seem to work with single-dimension vectors, and I can't seem to extrapolate to the 2-D world. I am an R novice, so please feel free to correct my misuse of terms here!

Upvotes: 1

Views: 6865

Answers (3)

Chris
Chris

Reputation: 93

Check the fields package (https://github.com/NCAR/fields) and especially the very helpful vignette: https://github.com/NCAR/fields/blob/master/fieldsVignette.pdf

Upvotes: 0

Alex Brown
Alex Brown

Reputation: 42932

To do 1-d smoothing in either the vertical or horizontal axis, use apply:

apply(myarray,1,smooth.spline)

or

apply(myarray,2,smooth.spline)

I'm not familiar with 2-D smoothing, but a quick experiment with the fields package seemed to work. You will need to install the package fields and it's dependencies. Where myMatrix is the matrix you had above... (I recreate it):

# transform data into x,y and z
m = c(1,1,2,1,1,5,6,3,2,3,2,1,1,1,1,1)
myMatrix = matrix(m,4,4,T)
myMatrix
     [,1] [,2] [,3] [,4]
[1,]    1    1    2    1
[2,]    1    5    6    3
[3,]    2    3    2    1
[4,]    1    1    1    1
Z = as.vector(myMatrix)
XY=data.frame(x=as.numeric(gl(4,1,16),Y=as.numeric(gl(4,4,16))
t=Tps(XY,Z)
surface(t)

Produced a pretty plot.

Upvotes: 8

Dirk is no longer here
Dirk is no longer here

Reputation: 368539

Smoothing is a big topic, and many functions are available in R itself and via additional packages from places like CRAN. The popular book 'Modern Applied Statistics with S' by Venables and Ripley lists a number of them in Section 8.1: (I think -- my 4th edition is at work) and Figure 8.1:

  • Polynomial regression: lm(y ~ poly(x))
  • Natural splines: lm(y ~ ns(x))
  • Smoothing splines: smooth.splines(x, y)
  • Lowess: lowess(x, y) (and a newer / preferred method
  • ksmooth: ksmooth(x, y)
  • supsmu: spusmu(x, y)

If you install the MASS package that goes with the book, you can run this via the file scripts/ch08.R and experiment yourself.

Upvotes: 8

Related Questions