Read Netcdf sub categories and convert to grid - r

I also posted this question on stack gis 1. From the netcdf4 data that have sub categories, I want to be able to read "Retrieval/fs" variable. I also want to read them and convert to raster girds, but it seems that raster doesn't support netcdf4. I appreciate any suggestions.
library(ncdf4)
library(raster)
file <- "http://140906_B7101Ar_150909171225s.nc4"
names(file$var)
"latitude" ... "longitude"... "Retrieval/fs"
lat <- raster(file, varname="latitude")
lon <- raster(file, varname="longitude")
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘raster’ for signature ‘"ncdf4"’

raster does work with ncdf4 You are now showing actual code. file is a character vector. You cannot do names(file$var) with that (at least you won't get "latitude" ... "longitude"... "Retrieval/fs". So file is probably ncdf4 object (see the error message), while the raster function expects a filename (but not a url).
If you download the file and then do
library(raster)
x <- brick(filename, var="Retrieval/fs")
Things should work if the ncdf file had regular raster data.
However, it does not so you cannot directly import this as a raster. Instead you can get the lat and lon and values from the files, treat these as points and then rasterize (interpolate) these to get a regular raster.

Here is the answer to the question I asked. Since the data is not gridded, I retrieve the lon and lat information along with the variables to create a dataframe.
fs <- ncvar_get(ncfile, "Retrieval/fs")
xlon <- ncvar_get(ncfile, "longitude")
xlat <- ncvar_get(ncfile, "latitude")
d <- data.frame( as.vector(xlon),as.vector(xlat), as.vector(fs))# create a dataframe
coordinates(d) <- c("xlon","xlat")
proj4string(d) <- CRS("+proj=longlat")
spoint <- SpatialPoints(coords = d) #create a spatial point object

Related

Why does cropping a raster stack changes the names of layers?

I'm processing yearly multilayer netCDF files with daily precipitation data from CHIRPS. I have the files for the whole world, each file about 1.2gb large. I need to calculate indices from the precipitation data for each cell in the raster for a specific region. In order to do that I'm trying to crop the files to get a rectangular shape above my area of interest using the raster R package.
This is the code I'm using, exemplary for the first file.
library(ncdf4)
library(raster)
library(rgdal)
# Crop extent
crop_extent <- as(raster::extent(79, 89, 25, 31), "SpatialPolygons")
proj4string(crop_extent) <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
# Set directory with original files
setwd("~/data")
# Read file
chirps81 <- stack("chirps-v2.0.1981.days_p05.nc")
chirps81crop <-crop(chirps1981, crop_extent)
# Write cropped file back to different folder
setwd("~/croppeddata")
writeRaster(chirps81crop, "chirps81crop.nc", overwrite=TRUE)
For some reason however while writing the file the layers lose their name. In the original files and after cropping the names have layer names of the format "X1981.01.01". But after writing and reading the netCDF file with new file <- stack("chirps81crop.nc") the layer names are changed to the format 'X1' up to 'X365'. I think it should be fine working with it, assuming that the order of the layers didn't get mixed up but I don't understand what is happening to the layer names and if this happens because there is something wrong with the code.
It's the writeRaster() function that is losing the layer names, not the crop operation. It is possible to use lower level ncdf functions to assign a numeric value (not a string unfortunately) to each layer which will then show up in the name of the layers after reading. Taking inspiration from the example here, I created some code that shows this.
library(ncdf4)
library(raster)
library(rgdal)
# Crop extent
crop_extent <- as(raster::extent(5.74, 5.75, 50.96, 50.97), "SpatialPolygons")
proj4string(crop_extent) <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
# make a sample file
r <- raster(system.file("external/test.grd", package="raster"))
r.latlon <- projectRaster(r, crs = proj4string(crop_extent))
writeRaster(x=r.latlon, filename = 'test.nc', format = 'CDF', overwrite=TRUE)
# read the sample as a 2 layer stack and crop it
test <- stack('test.nc', 'test.nc')
writeRaster(test, 'teststack.nc', overwrite=TRUE, format='CDF')
testcrop <- crop(test, crop_extent)
names(testcrop)
# [1] "test.1" "test.2"
# write the cropped file and make the zname equal to Layer
writeRaster(testcrop, 'testcrop.nc', overwrite=TRUE, format='CDF', zname='Layer')
# open the cdf file directly
nc <- nc_open('testcrop.nc', write = T)
# give the layers numbers starting from 10 so
# we can see them easily
layers = 1:nlayers(testcrop) + 10
layers
# [1] 11 12
ncvar_put(nc, 'Layer', layers)
nc_close(nc)
newtestcrop <- stack('testcrop.nc')
names(newtestcrop)
# [1] "X11" "X12"
nc <- nc_open('testcrop.nc', write = F)
layers = ncvar_get(nc, 'Layer')
layers
# [1] 11 12
nc_close(nc)
So it is possible to get names with numbers under your control when writing the raster, but I don't know enough about your environment to determine if this will help since it might be tricky to map the names you need to a single unambiguous number.
I hope you don't mind me offering a non-R solution, but this task is much easier from the command line using CDO:
cdo sellonlatbox,79,89,25,31 chirps-v2.0.1981.days_p05.nc cropped_file.nc
Which indices did you want to calculate? I suspect it is possible to calculate those quickly and easily with CDO functions too...

Convert SpatialCollections to SpatialPolygonsDataFrame in R

I am struggling to convert an object of class SpatialCollections to a SpatialPolygonsDataFrame object.
My input files are both shapefiles and SpatialPolygonsDataFrame objects. They can be accessed here.
I do an intersection of both objects:
SPDF_A <- shapefile("SPDF_A")
SPDF_B <- shapefile("SPDF_B")
intersection <- gIntersection(gBuffer(SPDF_A, width=0), gBuffer(SPDF_B, width=0))
The result is:
> intersection
class : SpatialCollections
Setting gBuffer(... , byid=T) or gBuffer(... , byid=F) seems to make no difference.
I use gIntersection and gBuffer(... , width=0) insetead of intersect in order to avoid geometrical problems (Self-intersection).
This is part of a larger loop. I need to get the intersection as SpatialPolygonsDataFrame because it will be saved as shp file in a following step.
writeOGR(intersection, ".", layer=paste0("Int_SPDF_A-SPDF_B"), driver="ESRI Shapefile")
This is not possible from a SpatialCollections object. In order to convert this to a SpatialPolygonsDataFrame I tried:
intersection <- as(intersection ,"SpatialPolygonsDataFrame")
intersection <- SpatialPolygonsDataFrame(intersection)
intersection <- readOGR(intersection, layer = "intersection")
Nothing works. Does anybody have a solution? Thanks a lot!
First of all, according to the documentation SpatialCollections is kind of a container format that can "hold SpatialPoints, SpatialLines, SpatialRings, and SpatialPolygons (without attributes)". If you need the data frame part of your SpatialPolygonsDataFrame ("attribute table" in GIS language), you'll have to work around that somehow. If, on the other hand, you're only interested in the spatial information (the polygons without the data attached to them) try the following:
str(intersection, max.level = 3)
suggests that the #polyobj is nothing but a SpatialPolygons object. Hence
mySpoly <- intersection#polyobj
should do the trick and
class(mySpoly)
suggests that we indeed now have a SpatialPolygons.
You need to convert that to a SpatialPolygonsDataFrame before exporting:
mySpolyData <- as(mySpoly, "SpatialPolygonsDataFrame")
writeOGR(mySpolyData, ".", layer=paste0("Int_SPDF_A-SPDF_B"), driver="ESRI Shapefile")

export khrud object from kernelUD to raster

In R, how can I export a khrud object from function kernelUD in package adehabitat to a raster file (geoTiff)?
I tried following this thread (R: how to create raster layer from an estUDm object) using the code here:
writeRaster(raster(as(udbis1,"SpatialPixelsDataFrame")), "udbis1.tif")
where udbis1 is a khrud object, but I get "Error in as(udbis1, "SpatialPixelsDataFrame") : no method or default for coercing “khrud” to “SpatialPixelsDataFrame."
I think the issue may be that the old thread was before an update to the adehabitat package changed the data format from estUD to khrud. Maybe?
You do not provide a reproducible example. The following works for me:
library(adehabitatHR)
library(raster)
data(puechabonsp)
loc <- puechabonsp$relocs
ud <- kernelUD(loc[, 1])
r <- raster(as(ud[[1]], "SpatialPixelsDataFrame"))
writeRaster(r, filename = file.path(tempdir(), "ud1.tif"))
AdehabitatHR solutions work well for data that are in the required format or when using multiple animals. Though when wanting to create KDE with data organized differently or for only one source, it can be frustrating. For some reason, #johaness' answer doesn't work for my case so here is an alternative solution that avoids the headaches of going into adehabitatHR's innards.
library(adehabitatHR)
library(raster)
# Recreating an example for only one animal
# with a basic xy dataset like one would get from tracking
loc<-puechabonsp$relocs
loc<-as.data.frame(loc)
loc<-loc[loc$Name=="Brock",]
coordinates(loc)<-~X+Y
ud<-kernelUD(loc)
# Extract the UD values and coordinates into a data frame
udval<-data.frame("value" = ud$ud, "lon" = ud#coords[,1], "lat" = ud#coords[,2])
coordinates(udval)<-~lon+lat
# coerce to SpatialPixelsDataFrame
gridded(udval) <- TRUE
# coerce to raster
udr <- raster(udval)
plot(udr)

Batch convert .csv files to .shp files in R

I am trying to convert a large number (>500) of text files into shapefiles. I can successfully convert a single .csv into a projected shapefile. And I can get lapply and 'for' loops to work when just loading, cleaning up, and exporting the text files. But the code fails when I add in steps to convert to shapefiles within the loops. Below are two ways I've tried tackling the problem and the associated error messages:
General processing/definitions-
library(rgdal)
library(sp)
crs.geo<-CRS("+proj=utm +zone=14 +ellps=GRS80 +datum=NAD83 +units=m +no_defs ") #define projection
coltype=c("character","character","character","numeric","numeric") #define data types for input .csv (x,y UTM coords are columns 4,5)
setwd("C:/.../testdata/out")
all.the.filenames <- list.files(pattern= "\\.csv") #create list of files to batch process
head(exampledata,2)
Point Location Time easting northing
1 Trackpoint 14 S 661117 3762441 12/1/2008 5:57:02 AM 661117 3762441
2 Trackpoint 14 S 661182 3762229 12/1/2008 5:58:02 AM 661182 3762229
Batch conversion with a 'for' loop
names <- substr(all.the.filenames, 1, nchar(all.the.filenames)-4) #clean up file names
for(i in names) {
filepath <- file.path("../out",paste(i,".csv",sep=""))
assign(i, read.table(filepath, colClasses=coltype, header=TRUE, sep=",", na.strings=c("NA","")))
coordinates(i) <- c(4,5) #coords in columns 4,5
proj4string(i) <- crs.geo
writeOGR(i,"C:/Users/Seth/Documents/testdata/out","*",driver="ESRI Shapefile") }
R returns this error message:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘coordinates<-’ for signature ‘"character"’
If I end the 'for' loop after the 'assign' line, it successfully imports all .csv files as separate objects in R. The problem seems to be that function 'coordinates' is not seeing the coords as numeric, and I get the same error message no matter how explicitly I try to define them as such (e.g., coordinates(i) <- c(as.numeric("easting","northing")) Also, these lines of code work successfully when applied to a single .csv file, the problem is when I subset within a loop.
Batch conversion using lapply
files.to.process <- lapply(all.the.filenames, function(x) read.csv(x, colClasses=coltype, header=TRUE))
lapply(files.to.process, function(c) coordinates(c)<-c("easting","northing"))
[[1]]
[1] "easting" "northing"
[[2]]
[1] "easting" "northing"
[[3]]
[1] "easting" "northing"
[[4]]
[1] "easting" "northing"
[[5]]
[1] "easting" "northing"
lapply(files.to.process, function(p) proj4string(p) <- crs.geo)
which returns the error message:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘proj4string<-’ for signature ‘"data.frame", "CRS"’
#Double-check if function 'coordinates' worked
class(files.to.process) == "SpatialPoints"
[1] FALSE
Conclusion/problem
With both approaches the problem seems to be in the 'coordinates' step to make a spatial object. What am I doing wrong in the loops? Thanks much for any help!
Seth H.
In your first attempt, the object i inside the loop is a character object. So,
coordinates(get(i))
would work better; I don't have a batch of csv files to test it on.
In the second attempt using lapply(), I'm not exactly sure what's going on, but
class(files.to.process)
should be "list", so what you want to do is
lapply(files.to.process,class)
and that will tell you if the objects are of class spatialpoints. I'm guessing they are data.frames, and you need one more step in between.

Read shape file with readOGR verses readShapePoly

I have read a shapefile using readShapePoly in the maptools package, but cannot read that same file with readOGR. I am hoping someone may be able to help me read the shapefile with readOGR.
I downloaded the file orcounty.shp from here: http://geography.uoregon.edu/geogr/topics/maps.htm
I also downloaded the associated files: orcounty.shx, orcounty.sbx, orcounty.sbn, and orcounty.dbf and put all five files in the folder: c:/users/mark w miller/gis_in_R/shapefile_example/
The following code reads the shapefile and displays some attributes:
library(maptools)
setwd('c:/users/mark w miller/gis_in_R/shapefile_example/')
# Oregon county census data (polygons)
orcounty.poly <- readShapePoly('orcounty.shp', proj4string=CRS("+proj=longlat"))
orcounty.line <- readShapeLines('orcounty.shp', proj4string=CRS("+proj=longlat"))
# see projection
summary(orcounty.poly)
Object of class SpatialPolygonsDataFrame
Coordinates:
min max
x -124.55840 -116.46944
y 41.98779 46.23626
Is projected: FALSE
proj4string : [+proj=longlat]
Data attributes:
However, when I try to read that same shapefile using the following code I receive an error:
library(rgdal)
# read shapefile
oregon.map <- readOGR(dsn="c:/users/mark w miller/gis_in_R/shapefile_example/", layer="orcounty")
# convert to dataframe
oregon.map_df <- fortify(oregon.map)
The error message says:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv) :
Cannot open file
I can read Natural Earth http://www.naturalearthdata.com/ shapefiles using:
library(rgdal)
setwd("c:/users/mark w miller/gis_in_R/")
# read shapefile
wmap <- readOGR(dsn="ne_110m_physical", layer="ne_110m_land")
So, apparently there is a difference between the Natural Earth shapefiles and the Oregon shapefile orcounty.shp.
Thank you for any advice on how to read orcounty.shp with readOGR. My question is similar to the question here: rgdal / readOGR - unable to read shapefile from .zip
Try to remove your last '/' from file path.
readOGR(dsn = 'c:/users/mark w miller/gis_in_R/shapefile_example',
layer = 'orcounty')
For anyone ending up here with this error on a Linux box, I found the problem was using a home path shortcut. i.e.
# Works
readOGR(dsn="/home/user/dir", layer="file")
# Doesn't work
readOGR(dsn="~/dir", layer="file")
I have no idea why.
I used the file ne_110m_land
Try with this:
setwd('D:/JMSR/codes.R/mapas')
unzip("ne_110m_land.zip")
ogrInfo(".", "ne_110m_land")
wmap <- readOGR(".", "ne_110m_land")
raster::shapefile wraps around readOGR to take care of paths and tildes; just pass the full file name.
library(raster)
x <- shapefile("c:/users/orcounty.shp')
or
y <- shapefile("~/users/orcounty.shp")

Resources