0

Is it possible to write a matrix of string variables to a netCDF file in R? When I run the following the R session aborts.

library(ncdf4)

# define a small set of netCDF dimensions
lon3 <- seq(0, 2.0, 0.5)
nlon3 <- length(lon3)
lat3 <- seq(0, 0.5, 0.5)
nlat3 <- length(lat3)
# Make the matrix of strings
id_matrix <- matrix(c("top_extreme_left", "top_left", "top_centre", "top_right", "top_extreme_right", "bottom_extreme_left", "bottom_left", "bottom_centre", "bottom_right", "bottom_extreme_right"), nrow=2, byrow = TRUE)

# create and write NetCDF file
# path and file name, set dname
ncpath <- "C:/"
ncname <- "tiny_test_netcdf"
ncfname <- paste(ncpath, ncname, ".nc", sep="")

# create and write the netCDF file -- ncdf4 version
# define dimensions
londim <- ncdim_def("lon","degrees_east",as.double(lon3)) 
latdim <- ncdim_def("lat","degrees_north",as.double(lat3))
# dimension for each char in the strings (max string length of 25 characters)
dimchar <- ncdim_def("nchar", "", 1:25, create_dimvar = FALSE)

# define variables
dlname <- "test string matrix data"
id_def <- ncvar_def("op_id", "", list(londim, latdim, dimchar), longname = dlname, prec="char")

# create netCDF file and put arrays
ncout <- nc_create(ncfname, list(id_def), force_v4=TRUE)

# Put the matrix of id strings into the netCDF file.
ncvar_put(ncout, id_def, id_matrix, start=c(1,1,1), count = c(5, 2, 25), verbose = TRUE)

# Close the file to write the data
nc_close(ncout)

I'm attempting to extend the example given in the help for ncvar_put which shows the process for a vector of strings. Any idea how/if it's possible to do the same with a matrix?

Dave_L
  • 363
  • 2
  • 10

1 Answers1

1

Eventually found a way by formatting the strings to write into a vector first rather than a matrix. You just have to be mindful that the writing will place the strings into the correct X,Y locations (X grows fastest).

#----------------------------------------------------------------------
# Illustrate creating a character type variable
#----------------------------------------------------------------------
cnames   <- c("bottom_extreme_left", "bottom_left", "bottom_centre", "bottom_right", "bottom_extreme_right", "top_extreme_left", "top_left", "top_centre", "top_right", "top_extreme_right")
nstrings <- length(cnames)
max_length <- max(nchar(cnames))

dimX <- ncdim_def( "X", "lon", c(1,2,3,4,5))
dimY <- ncdim_def( "Y", "lat", c(1,2))

#--------------------------------------------------------------
# Make dimensions. Setting "dimnchar" to have a length equa to max string length in data
dimnchar   <- ncdim_def("nchar",   "", 1:max_length, create_dimvar=FALSE )

#------------------------------------------------------------------------
# NOTE in the following call that units is set to the empty string (""),
# which suppresses creation of a units attribute, and the missing value
# is entirely omitted, which suppresses creation of the missing value att
#------------------------------------------------------------------------
varlocations  <- ncvar_def("locations", "", list(dimnchar, dimX, dimY), 
                        prec="char" )

# path and file name
ncpath <- "C:/"
ncname <- "tiny_test_netcdf"
ncfname <- paste(ncpath, ncname, ".nc", sep="")
ncid <- nc_create(ncfname, list(varlocations) )

ncvar_put( ncid, "locations", cnames, verbose=TRUE )

nc_close( ncid )
Dave_L
  • 363
  • 2
  • 10