I'm trying to smooth a 11 X 8 matrix and I can't seem to find a way to do this. I know there are several threads on this but none has helped for my situation. Every approach I've found requires some sort of z ~ x*y approach. In my case I just have a matrix that I would like to simply smooth all of the cell entries to make a smoother surface plot.

m
       [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]      [,8]
[1,] 29.02530 28.57123 39.02334 38.25483 29.59624 65.01706 41.04771  98.62005
[2,] 24.46539 24.08265 32.89272 32.24494 24.94663 54.80279 34.59906  83.12670
[3,] 28.30679 27.86395 38.05733 37.30784 28.86359 63.40758 40.03159  96.17873
[4,] 24.99883 24.60774 33.60991 32.94800 25.49056 55.99770 35.35345  84.93918
[5,] 24.63308 24.24771 33.11817 32.46595 25.11761 55.17842 34.83621  83.69646
[6,] 29.85776 29.39066 40.14254 39.35199 30.44506 66.88177 42.22497 101.44850
[7,] 18.54275 18.25267 24.92998 24.43901 18.90749 41.53601 26.22324  63.00320
[8,] 24.43846 24.05615 32.85652 32.20945 24.91917 54.74248 34.56098  83.03522
[9,] 27.09827 26.67434 36.43252 35.71503 27.63130 60.70048 38.32249  92.07251
[10,] 37.11375 36.53313 49.89792 48.91525 37.84378 83.13528 52.48642 126.10236
[11,] 26.06763 25.65982 35.04686 34.35666 26.58038 58.39182 36.86495  88.57066

library(lattice)
wireframe(m)

surface plot not smoothed

any ideas?

有帮助吗?

解决方案

Whatever you end up doing, you'll need some model to smooth the data you have. You could use a wide range of models to do the smoothing but the one I am most familiar with is the penalised regression spline approach to fitting GAMs via the mgcv package, which also happens to come with R.

Firs, some simulated data

set.seed(1)
m <- matrix(runif(11*8), ncol = 8)

To model these, you need them in the form z ~ x + y, i.e. long format where there is a row for every z (cell in your matrix). So, arrange our example data into long format

df <- data.frame(x = rep(seq_len(ncol(m)), each = nrow(m)),
                 y = rep(seq_len(nrow(m)), times = ncol(m)),
                 z = c(m))

> head(df)
  x y         z
1 1 1 0.2655087
2 1 2 0.3721239
3 1 3 0.5728534
4 1 4 0.9082078
5 1 5 0.2016819
6 1 6 0.8983897

Here x varies slowest and refers to the columns, y fastest and refers to the rows. Next load mgcv and fit the model

require("mgcv")
mod <- gam(z ~ te(x, y), data = df)

The model is a 2d tensor product spline of the x and y "locations`.

To replicate your plot, but smoother, take the fitted values of the model and arrange as a matrix again

m2 <- matrix(fitted(mod), ncol = 8)

Then plot

require("lattice")
wireframe(m2)

enter image description here

Depending on what you are doing, you can control the degree of smoothness via two options to te():

  1. k sets the degrees of freedom or complexity of the smooths. Here is really sets the initial dimensions of the basis functions, which are then shrunk to some "optimal dimensionality via the penalised regression. For the tensor product spline fitted via te(), you can specify k for both dimensions of the spline. To set k = 5 in both directions use te(x, y, k = 5). To have different basis dimensions use te(x, y, k = c(10,5)) for example to have dimension 10 basis functions for x and dimension 5 for y.

  2. Fix the degrees of freedom, i.e. don't do any of the penalisation I mentioned above. You do this by adding fx = TRUE to the te() call. To continue the last example, te(x, y, k = c(10,5), fx = TRUE) will use the basis functions as above but won't shrink down from this to some smaller number of degrees of freedom.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top