0

I'm trying to write a .nc file from a .csv file.

This is PART of my .csv table (df)

 long        lat     elev
1  -47.99206  -7.501234 242.0362
2  -47.99206  -7.751234 200.7271
3  -47.99206  -8.001234 165.6918
4  -47.99206  -8.251234 271.2571
5  -47.99206  -8.501234 235.2896
6  -47.99206  -8.751234 271.5381
7  -47.99206  -9.001234 290.0054
8  -47.99206  -9.251234 218.8803
9  -47.99206  -9.501234 261.7539
10 -47.99206  -9.751234 318.0000
11 -47.99206 -10.001234 314.3667
12 -47.99206 -10.251234 386.0861
13 -47.99206 -10.501234 446.0594
14 -47.99206 -10.751234 733.0910
15 -47.99206 -11.001234 316.2924
16 -47.99206 -11.251234 264.8820
17 -47.74206  -7.501234 262.5883
18 -47.74206  -7.751234 197.8402
19 -47.74206  -8.001234 246.0610
20 -47.74206  -8.251234 264.7328

...

As you can see I have two dimensions and one variable.

This is the code I'm using:

xvals <- unique(df$long)
xvals <- xvals[order(xvals)]
yvals = unique(df$lat)
yvals <- yvals[order(yvals)] 

lon <- ncdim_def("longitude", "degrees", xvals)
lat <- ncdim_def("latitude", "degrees", yvals)

var_elev <- ncvar_def("elev", "m above sea", 
                      list(lon, lat), NA) 

ncnew <- nc_create('elev.nc', var_elev)

ncvar_put(ncnew, "elev", df$elev, count = c(35, 51))

When I run the last line, I get this error message:

Error in ncvar_put(ncnew, "elev", df$elev, count = c(35, 51)) : 
  ncvar_put: error: you asked to write 1785 values, but the passed data array only has 959 entries!

More information about my dimensions:

yvals unique values:

yvals
 [1] -15.001234 -14.751234 -14.501234 -14.251234 -14.001234
 [6] -13.751234 -13.501234 -13.251234 -13.001234 -12.751234
[11] -12.501234 -12.251234 -12.001234 -11.751234 -11.501234
[16] -11.251234 -11.001234 -10.751234 -10.501234 -10.251234
[21] -10.001234  -9.751234  -9.501234  -9.251234  -9.001234
[26]  -8.751234  -8.501234  -8.251234  -8.001234  -7.751234
[31]  -7.501234  -7.251234  -7.001234  -6.751234  -6.501234
[36]  -6.251234  -6.001234  -5.751234  -5.501234  -5.251234
[41]  -5.001234  -4.751234  -4.501234  -4.251234  -4.001234
[46]  -3.751234  -3.501234  -3.251234  -3.001234  -2.751234
[51]  -2.501234

xvals unique values:

xvals
 [1] -50.49206 -50.24206 -49.99206 -49.74206 -49.49206 -49.24206
 [7] -48.99206 -48.74206 -48.49206 -48.24206 -47.99206 -47.74206
[13] -47.49206 -47.24206 -46.99206 -46.74206 -46.49206 -46.24206
[19] -45.99206 -45.74206 -45.49206 -45.24206 -44.99206 -44.74206
[25] -44.49206 -44.24206 -43.99206 -43.74206 -43.49206 -43.24206
[31] -42.99206 -42.74206 -42.49206 -42.24206 -41.99206

And elev column has 959 unique values.

Additionaly, I'm not sure that reorder the dimensions will give me the right correspondence between long, lat and elev. Anyway, I'm completely lost how to solve this problem.

Thanks everyone!

  • Hi, in the last line, I think `elev` should be `"elev"` (i.e. a string). Can you tell the size of `var_elev` and the size of `df$elev`? They apparently do not match. – Chelmy88 Jan 17 '20 at 09:09
  • Yes sure, I made the correction and update the error message. The same error appears, however with different numbers. Also, `var_elev$varsize` returns `35 51`. – Fabio Seixas Jan 17 '20 at 11:35

1 Answers1

1

you are trying to define a 2D array with ncdim_def, but only pass a 1D vector to the dataset. You need to convert the observations of your dataframe to a 2D array. This can be done with tidyr:

library(tidyr)
# Example df with same names
df <- data.frame(long = rep(1:10,2), lat = 1:40, elev = 1:40)
# Creates a 2D array
df_new <- tidyr::pivot_wider(df, names_from = long, values_from = elev)
df_new <- df_new[,-1]

Now try

ncvar_put(ncnew, elev, as.matrix(df_new))
SebSta
  • 476
  • 2
  • 12
  • I tried to implement your solution with no success. I get the following error: `Error in ncvar_put(ncnew, varid = "elev", vals = df_new) : (list) object cannot be coerced to type 'double'` – Fabio Seixas Jan 17 '20 at 11:53
  • In the ncvar_put function call, change df_new to as.matrix(df_new), i forgot about that. – SebSta Jan 17 '20 at 12:01