简体   繁体   中英

In R with ncdf4, open netcdf file, modify, and save to disk

I am trying modify and save a netcdf file in R. I can modify the values, but cannot seem to get the file to save and keep the modified values. Here is what I am doing:

Open file with ncdf4 package

library(ncdf4)
nc=nc_open('RMinit_newvalues2017.nc', write=T)

Reassign missing values - The file is has 2000 variables, about half need to have their missing values modified, I can successfully do that:

for (i in 1:10){
   print(nc$var[[i]]$name) # use to match aaR/aaS
   test=grep("_Nums", nc$var[[i]]$name) # search for Nums, skip to next
   if (length(test) ==1){
     next
   }
   test2=grep("_ResN", nc$var[[i]]$name) # search for RN
    if (length(test2) == 1) {
      print(nc$var[[i]]$missval) # print orginal value
      print(xR$RN[which(xR$Variables==nc$var[[i]]$name)]) # print new value
      nc$var[[i]]$missval=xR$RN[which(xR$Variables==nc$var[[i]]$name)] # assign new value
      print(nc$var[[i]]$missval) # print assigned value

    } else if (length(test2) != 1) {
       print(nc$var[[i]]$missval)
       print(xS$SN[which(xS$Variables==nc$var[[i]]$name)])
       nc$var[[i]]$missval=xS$SN[which(xS$Variables==nc$var[[i]]$name)]
       print(nc$var[[i]]$missval)

    }
}

Here is annotated output to show it is changing values for '_ResN' and '_StructN':

[1] "Anchovies10_Nums" (nothing done here, next)
[1] "Anchovies10_ResN" (first replacement)
[1] 987.7794 (original value)
[1] 200.1975 (replacement value, printed after assignment)
[1] "Anchovies10_StructN" (repeat pattern...)
[1] 372.7469
[1] 75.54621
[1] "Anchovies1_Nums"
[1] "Anchovies1_ResN"
[1] 130.3665
[1] 15.67022
[1] "Anchovies1_StructN"
[1] 49.19491
[1] 5.913289
[1] "Anchovies2_Nums"
[1] "Anchovies2_ResN"
[1] 228.1891
[1] 34.30677
[1] "Anchovies2_StructN"
[1] 86.10911
[1] 12.94595
[1] "Anchovies3_Nums"

Lastly, I sync and close the nc file, which should save it to disk. But nothing happens here. No errors, everything seems fine, except the file is not saved. What am I missing???

nc_sync(nc)
nc_close(nc)

EDIT: I was able to get the files to save after switching commands in the loop. using ncatt_put versus assigning with nc$var[[i]]$missval=... seemed to fix the problem. I also realised I was editing the wrong value to begin with, as I needed the _Fillvalue to change, not the missval . This now works:

for (i in 1:dim(a)[1]){
test=grep("_Nums", nc$var[[i]]$name) # search for Nums, skip to next
if (length(test) ==1){
  next
}
test2=grep("_ResN", nc$var[[i]]$name) # search for RN
if (length(test2) == 1) {
  ncatt_put(nc,a[i,1],"_FillValue", xR$RN[which(xR$Variables==nc$var[[i]]$name)])
} else if (length(test2) != 1) {
  ncatt_put(nc,a[i,1],"_FillValue", xS$SN[which(xS$Variables==nc$var[[i]]$name)])  
}
nc_sync(nc)
}
nc_sync(nc)
nc_close(nc)

Posting my solution as an FYI to maybe help someone down the road...

I solved my problem for the time being. Still not sure why the first attempt did not update the file. I needed to use ncdf4::ncatt_put to edit the attribute for _FillValue and ncdf4::ncvar_put to add the data. Then doing a nc_sync within the loop helped.

for (i in 1:length(b)){
  vv=as.numeric(b[i]) # index of ResN and StructN in entire list of nc file 'a'
  testSN=grep("_StructN", a[vv,1]) # use to select SN values
  testRN=grep("_ResN", a[vv,1]) # use to select RN values

  if (length(testRN) ==1){
    ncatt_put(nc,a[vv,1],"_FillValue", xR$RN[which(xR$Variables==a[vv,1])])
    ncvar_put(nc,a[vv,1], rep(xR$RN[which(xR$Variables==a[vv,1])],150)) # replicate 5x30
  } else if (length(testSN) ==1){
    ncatt_put(nc,a[vv,1],"_FillValue", xS$SN[which(xS$Variables==a[vv,1])])
    ncvar_put(nc,a[vv,1], rep(xS$SN[which(xS$Variables==a[vv,1])],150))
  }
  nc_sync(nc)
}
nc_sync(nc)
nc_close(nc)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM