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 bookhttp://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>
Errr... You could reshape to a long format data.frame but an arguably easier way: dimnames(array.3d) <- list(lat= 1:7 , long = 1:11 , lev = 1:5) # not needed just for clarity levelplot(array.3d) On Sat, Nov 17, 2012 at 9:36 PM, Tom Roche <Tom_Roche@pobox.com> wrote:> > 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@pobox.com> > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
https://stat.ethz.ch/pipermail/r-help/2012-November/329438.html>> 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)much detail omitted ...>> I'm guessing this involves function=reshapehttps://stat.ethz.ch/pipermail/r-help/2012-November/329439.html> an arguably easier way: > dimnames(array.3d) <- list(lat= 1:7 , long = 1:11 , lev = 1:5) > levelplot(array.3d)I know levelplot will do arrays directly, but I don't see how to get the naming I want without a dataframe: am I missing something? Thanks to zero_one for offlist pointer to reshape2::melt: library(reshape2) data.frame <- melt(array.3d, varnames=c("lon", "lat", "lev"), value.name="conc") library(lattice) levelplot(conc ~ lon * lat | factor(lev), data = data.frame) works! thanks all, Tom Roche <Tom_Roche at pobox.com>
Maybe Matching Threads
- [lattice] format and rotation of strip text
- Extracting subset from netCDF file using lat/lon and converting into .csv in R
- [lattice] how to overlay a geographical map on a levelplot?
- Extracting subset from netCDF file using lat/lon and converting into .csv in R
- Unexpected values obtained when reading in data using ncdf and ncdf4