How to write a data frame to netcdf file in R

624 Views Asked by At

I have a data frame (df) in R, which represent a trajectory/track, including time, position, and ID. I would like to write it from R as a netCDF file. Here is the df:

df <-structure(list(ID = 1:7, longitude = c(43.064598540146, 43.1822580645161, 
43.4866310160428, 44.1001340482573, 43.9886235955056, 44.2082894736842, 
44.9320045558087), latitude = c(21.8770072992701, 21.7581290322581, 
21.7237967914438, 21.7701072386059, 21.5936797752809, 21.6146052631579, 
21.5759681093394), time = c(-1825639200, -1825635600, -1825632000, 
-1825628400, -1825624800, -1825621200, -1825617600)), class = "data.frame", row.names = c(NA, 
-7L))

Below what I have tried so far:

library(ncdf4)

dimLON <- ncdim_def("lon",
  units = "degrees_east",
  longname = "longitude",
  vals = seq(20, 70, 0.1)
)

dimLAT <- ncdim_def("lat",
  units = "degrees_north",
  longname = "latitude",
  vals = seq(-5, 40, 0.1)
)

# dummy time variable
dimTime <- ncdim_def("time",
  units = "hours since 1900-01-01 00:00:00.0",
  longname = "time",
  calendar = "gregorian",
  vals = as.numeric(seq(as.POSIXct("1912-02-24 23:00:00"),
    as.POSIXct("1912-02-25 08:32:00"),
    by = "hour"
  )[1:7]),
  unlim = TRUE
)

# define variables
fillvalue <- 1e32

dlname <- "storm_example"

var_def <- ncvar_def(
  name = dlname,
  units = "NA",
  list(dimLON, dimLAT, dimTime),
  fillvalue, dlname, prec = "double"
)


# create netCDF file and put arrays
ncoutput <- nc_create("../testing/track_example.nc",
  list(var_def),
  force_v4 = TRUE, verbose = TRUE
)
# put variable

ncvar_put(ncoutput, var_def, df)

# put additional attributes into dimension and data variables
ncatt_put(ncoutput, "lon", "axis", "X")
ncatt_put(ncoutput, "lat", "axis", "Y")
ncatt_put(ncoutput, "time", "axis", "T")

nc_close(ncoutput)
nc_close(ncin)

The error occurs when I run ncvar_put(ncoutput,var_def,df), the error is pretty clear, my question would is there any way to write the df to a netCDf file? The only file I encountered with track data is from IBTrACS, which is tropical cyclones datasets including tracks and features along the track.

The error:

> ncvar_put(ncoutput,var_def,df)
Error in ncvar_put(ncoutput, var_def, final) : 
  ncvar_put: error: you asked to write 1581657 values, but the passed data array only has 28 entries!

1

There are 1 best solutions below

1
On

According to your code, the ncvar_put function expects a three-dimensional array which has 501 * 451 * 7 = 1581657 elements where 501, 451, and 7 imply the total number of longitudes, latitudes, and time steps, respectively. So in this case the df cannot be written to a netCDF file since it has only two dimensions.

The values of df can be written to a netCDF file as follows. (For the sake of simplicity the file is created in the working directory.)

# Load the required R package:
library(ncdf4)

# Create the dimensions and the two-dimensional array:
nr_of_rows <- nrow(df)
nr_of_cols <- ncol(df)
df_array <- as.matrix(df)

# Define the dimensions:
dim1 <- ncdim_def("dim1", "", seq(nr_of_rows))
dim2 <- ncdim_def("dim2", "", seq(nr_of_cols))

# Define missing values:
fillvalue <- 1e32

# Define the variable:
var_def <- ncvar_def("var", "", list(dim1,dim2), fillvalue, prec="double")

# Create the file:
nc <- nc_create("example.nc", list(var_def))
ncvar_put(nc, var_def, df_array)

# Close the file:
nc_close(nc)

# Check the file (retrieve the dimensions and the values of df):
example_nc <- nc_open("example.nc")
ncvar_get(example_nc, "dim1")
ncvar_get(example_nc, "dim2")
ncvar_get(example_nc, "var")
nc_close(example_nc)

If this is not the solution what you are looking for then please specify the three-dimensional array you want to write to a netCDF file.