Reputation: 53
I have a set of observation in irregular grid. I want to have them in regular grid with resolution of 5. This is an example :
d <- data.frame(x=runif(1e3, 0, 30), y=runif(1e3, 0, 30), z=runif(1e3, 0, 30))
## interpolate xy grid to change irregular grid to regular
library(akima)
d2 <- with(d,interp(x, y, z, xo=seq(0, 30, length = 500),
yo=seq(0, 30, length = 500), duplicate="mean"))
how can I have the d2
in SpatialPixelDataFrame
calss? which has 3 colomns, coordinates and interpolated values.
Upvotes: 2
Views: 1842
Reputation: 60858
You can use code like this (thanks to the comment by @hadley):
d3 <- data.frame(x=d2$x[row(d2$z)],
y=d2$y[col(d2$z)],
z=as.vector(d2$z))
The idea here is that a matrix in R is just a vector with a bit of extra information about its dimensions. The as.vector
call drops that information, turning the 500x500 matrix into a linear vector of length 500*500=250000. The subscript operator [
does the same, so although row
and col
originally return a matrix, that is treated as a linear vector as well. So in total, you have three matrices, turn them all to linear vectors with the same order, use two of them to index the x
and y
vectors, and combine the results into a single data frame.
My original solution didn't use row
and col
, but instead rep
to formulate the x
and y
columns. It is a bit more difficult to understand and remember, but might be a bit more efficient, and give you some insight useful for more difficult applications.
d3 <- data.frame(x=rep(d2$x, times=500),
y=rep(d2$y, each=500),
z=as.vector(d2$z))
For this formulation, you have to know that a matrix in R is stored in column-major order. The second element of the linearized vector therefore is d2$z[2,1]
, so the rows number will change between two subsequent values, while the column number will remain the same for a whole column. Consequently, you want to repeat the x
vector as a whole, but repeat each element of y
by itself. That's what the two rep
calls do.
Upvotes: 3