[R] [newbie] convert 3D spatial array to dataframe
Tom Roche
Tom_Roche at pobox.com
Sun Nov 18 05:36:47 CET 2012
summary: how to convert a 3D array (as obtained from ncdf4::ncvar_get)
to a dataframe suitable for use by lattice::levelplot(), e.g.,
levelplot(conc ~ lon * lat | lev, data = data.frame)
details:
I have atmospheric data in netCDF files specifying gas concentrations
over a 3D space with dimensions longitude, latitude, and (vertical)
level. I need to plot the data by level. Since there are several levels,
I'm guessing I should use package=lattice, which I have not previously
used. (I have used package=fields, and I would like to plot the levels
over a map, but lattice seems to provide the best way to organize
multiple plots--please correct me if wrong.)
>From reading Sarkar's excellent lattice book
http://dx.doi.org/10.1007/978-0-387-75969-2
it seems that one best provides data to lattice::levelplot() via
dataframe, since the dataframe provides a sort of namespace for the
trellis "formula." I know that ncdf4::ncvar_get will return my
concentrations as the values in a 3D array with dimensions={lon, lat,
lev} so I'm trying to find a way to convert a 3D array to a dataframe.
Here's my small, self-contained example:
lon=11
lat=7
lev=5
len=lon*lat*lev
array.3d <- array(data=c(1:len), dim=c(lat, lon, lev))
# Rewrite the array values "more spatially," i.e., row-wise from
# bottom left. If there's a more-R-ish way to fill this array
# as specified, please let me know: I know 'for' loops are deprecated
# in R.
i=1
for (z in 1:lev) {
for (x in lat:1) {
for (y in 1:lon) {
array.3d[x,y,z]=i ; i=i+1
}
}
}
produces (with rows=latitudes and cols=longitudes)
> array.3d[,,1]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 67 68 69 70 71 72 73 74 75 76 77
[2,] 56 57 58 59 60 61 62 63 64 65 66
[3,] 45 46 47 48 49 50 51 52 53 54 55
[4,] 34 35 36 37 38 39 40 41 42 43 44
[5,] 23 24 25 26 27 28 29 30 31 32 33
[6,] 12 13 14 15 16 17 18 19 20 21 22
[7,] 1 2 3 4 5 6 7 8 9 10 11
> array.3d[,,lev]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 375 376 377 378 379 380 381 382 383 384 385
[2,] 364 365 366 367 368 369 370 371 372 373 374
[3,] 353 354 355 356 357 358 359 360 361 362 363
[4,] 342 343 344 345 346 347 348 349 350 351 352
[5,] 331 332 333 334 335 336 337 338 339 340 341
[6,] 320 321 322 323 324 325 326 327 328 329 330
[7,] 309 310 311 312 313 314 315 316 317 318 319
I want to convert array.3d to a dataframe with structure like the
following (note order of data values is arbitrary):
lon lat lev conc
--- --- --- ----
1 7 1 1
2 7 1 2
3 7 1 3
...
9 1 1 75
10 1 1 76
11 1 1 77
...
9 1 5 383
10 1 5 384
11 1 5 385
How to do that? I'm guessing this involves function=reshape, but I can't
see how to make `reshape` work for this usecase.
TIA, Tom Roche <Tom_Roche at pobox.com>
More information about the R-help
mailing list