I have .nc file sizing around 651 MB with a couple of datasets (daily) (rr_mrg_19810101_20181231_ENACT.nc) data. I need to convert (rr_mrg_19810101_20181231_ENACT.nc) dataset to multiple GeoTIFF (one .tif for each time slice, monthly). Similarly, i want to read the time series. But I found
Error in .local(x, time, ...) :
time must has the same length as the number of layers in RasterBrick][1]
Here is what i did
library(raster)
library(zoo)
library(rts)
TRF = brick("rr_mrg_19810101_20181231_ENACT.nc")
crs(TRF) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84
+towgs84=0,0,0"
Awash_Extent<-c(37,44, 7,12)
Awash_E_resize<- crop(TRF,Awash_Extent)
Awash_Month<-seq(as.Date('1981-01-01'),as.Date('2018-12-31'),by =
"month")
rt <- rts(Awash_E_resize, Awash_Month)
write.rts(Awash_E_resize, filename='Awash_TRF_1981_2018_mon.tif',
overwrite=TRUE)
Can you help me on the issue?
Something as simple as this can do that
library(raster)
b <- brick("rr_mrg_19810101_20181231_ENACT.nc")
writeRaster(b, "timeslice.tif", bylayer=TRUE)
Based on your expanded question:
Read the values with terra (no need for other packages)
library(terra)
TRF = rast("rr_mrg_19810101_20181231_ENACT.nc")
Awash_Extent<-c(37,44, 7,12)
Awash_E_resize<- crop(TRF,Awash_Extent)
I create something similar here:
A <- rast(ext(37,44, 7,12), nlyr=365)
values(A) <- runif(size(A))
terra::time(A) <- seq(as.Date('1981-01-01'), as.Date('1981-12-31'), 1)
Now aggregate by month:
m <- months(time(A))
f <- factor(m, levels=unique(m))
B <- tapp(A, m, fun=sum)
B
#class : SpatRaster
#dimensions : 10, 10, 12 (nrow, ncol, nlyr)
#resolution : 0.7, 0.5 (x, y)
#extent : 37, 44, 7, 12 (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84
#source : memory
#names : January, February, March, April, May, June, ...
#min values : 12.49764, 10.47718, 11.80974, 11.29624, 11.01105, 10.83298, ...
#max values : 18.90536, 16.95743, 20.57114, 18.12099, 18.46543, 18.98500, ...
You could add a filename= argument to tapp, but if you want to save the layers as separate files you can use writeRaster instead. But with terra you need to provide the filenames yourself.
fnames <- paste0("rain_", 1:nlyr(B), ".tif")
writeRaster(B, fnames, overwrite=T)
(there is a warning about file_ext that you can ignore)
Related
I'm looking for a tip on how to recode time/date dimension of a netcdf file/raster brick. I extracted a monthly temperature data and the date dimension is not in the standard date format. For example, 1850.04166666667, 1850.125, means January and February 1850 respectively in the data and R couldn't understand them. Here's the data structure
> eco.sst
class : RasterBrick
dimensions : 180, 360, 64800, 2030 (nrow, ncol, ncell, nlayers)
resolution : 1, 1 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : C:\Users\Admin\AppData\Local\Temp\Rtmp6vFWNG\raster\r_tmp_2019-04-18_183528_11516_79080.grd
names : X1850.04166666667, X1850.125, X1850.20833333333, X1850.29166666667, X1850.375, X1850.45833333333, X1850.54166666667, X1850.625, X1850.70833333333, X1850.79166666667, X1850.875, X1850.95833333333, X1851.04166666667, X1851.125, X1851.20833333333, ...
min values : -0.668686926, -0.273689777, -1.902773499, -3.406341553, -3.626811743, -2.131400585, -1.569969416, -1.630665064, -2.418994188, -1.971702099, -0.822018623, -3.423746109, -1.303600550, -0.786648691, -1.452626705, ...
max values : 3.926926e+00, 1.550823e+00, 1.151636e+00, 6.622851e-01, 9.673859e-01, 7.178870e-01, 9.010030e-01, 4.363060e-01, 5.231520e-01, 3.346115e-01, 2.156055e-01, 6.418970e-01, 2.259051e+00, 3.802529e+00, 2.077996e+00, ...
time : 1850.04166666667, 2019.125 (min, max)
I wrote a function to replace the decimal points;
fun.repl = function (x, na.rm = TRUE) str_replace(x, ".04166666667", "-1")
such that 1850.04166666667, which means January 1850 becomes 1850-1;
which I then applied to the raster in the form:
stackApply(eco.sst, "time", fun.repl)
eco.sst is the raster brick while "time" is referencing the time dimension. But the function did not work. I suspect that I don't understand the data structure well enough to successfully apply the function. I'm new to this and also finding out that this is a rare problem with netcdf.
I expect 1850.04166666667, 1850.125, 1850.20833333333, 1850.29166666667...which means January to April 1850 to become standard dates in the form.... 1850-1, 1850-2, 1850-3, 1850-4 etc
Here is another way to get the dates
todate <- function(x) {
year <- trunc(x)
month <- round(12 * ((x - year) + 1/24))
as.Date(paste0(year, "-", month, "-15"))
}
dts <- c(1850.04166666667, 1850.125)
d <- todate(dts)
d
#[1] "1850-01-15" "1850-02-15"
Note that I use the 15th day for each month in order to get a valid date --- but that seems to be what is intended.
Now you probably want to use setZ, see the example below. (stackApply makes no sense here and the arguments you use are not valid either)
library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(1:2, function(x) setValues(r, runif(ncell(r)))))
s <- setZ(s, d)
s
#class : RasterStack
#dimensions : 10, 10, 100, 2 (nrow, ncol, ncell, nlayers)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#names : layer.1, layer.2
#min values : 0.01477963, 0.01178438
#max values : 0.9980334, 0.9939610
#time : 1850-01-15, 1850-02-15
this might be rather simple, but I am a novice in R. I have tried for awhile now to plot two rasters against each other using boxplot from the package raster.
I have a DEM raster and a categorical raster that contains 4 cluster groups, which I would like to use as 'zones' as described in the manual:
boxplot(x, y=NULL, maxpixels=100000, ...)
x Raster* object
y If x is a RasterLayer object, y can be an additional RasterLayer to group the
values of x by ’zone’
> DEM
class : RasterLayer
dimensions : 12381, 61922, 766656282 (nrow, ncol, ncell)
resolution : 0.1, 0.1 (x, y)
extent : 478307.4, 484499.6, 6131862, 6133100 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs
data source : /Users/Yvonne/Desktop/Boxplot/Ribe_DEM_0.1m.tif
names : Ribe_DEM_0.1m
values : -7.523334, -0.36 (min, max)
> Cluster
class : RasterLayer
dimensions : 12381, 61922, 766656282 (nrow, ncol, ncell)
resolution : 0.1, 0.1 (x, y)
extent : 478307.4, 484499.6, 6131862, 6133100 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs
data source : /Users/Yvonne/Desktop/Boxplot/final_cluster.tif
names : final_cluster
values : 1, 4 (min, max)
attributes :
ID Rowid COUNT
1 0 463524
2 1 4118997
3 2 3390160
4 3 3218998
> boxplot(DEM, Cluster, xlab="Cluster", ylab="Elevation")
Error in parse(text = x, keep.source = FALSE) :
<text>:2:0: unexpected end of input
1: ~
^
In addition: Warning message:
In .local(x, ...) : taking a sample of 1e+05 cells
Update:
I just found a working example, which does exactly what I want. However if I run it with my own data I always get above error. Maybe someone could explain the error message. Would be really appreciated.
r1 <- r2 <- r3 <- raster(ncol=10, nrow=10)
r1[] <- rnorm(ncell(r1), 100, 40)
r2[] <- rnorm(ncell(r1), 80, 10)
r3[] <- rnorm(ncell(r1), 120, 30)
s <- stack(r1, r2, r3)
names(s) <- c('A', 'B', 'C')
rc <- round(r1[[1]]/100)
hist(rc)
summary(rc)
boxplot(s[[1]],rc)
Okey I found an answer, I don't know exactly why but it works for me:
I had to create a brick and then I could use the boxplot as mentioned above.
s <- stack(DEM, Cluster)
sbrick <- brick(s)
boxplot(sbrick[[1]], sbrick[[2]], xlab="Cluster", ylab="Elevation")
Resulting in this plot boxplot DEM against cluster groups
Thanks everyone for their help!
You can use bwplot function in rasterVis library.
Here is an example from rasterVis:
library(raster)
library(rasterVis)
r <- raster(system.file("external/test.grd", package="raster"))
s <- stack(r, r*2)
bwplot(s,violin=FALSE,strip=strip.custom(strip.levels=TRUE))
It is not clear to me why you get that error. Perhaps you can run the code below and see for yourself:
x <- stack(DEM, Cluster)
s <- sampleRegular(s, 100000, useGDAL=TRUE)
cn <- colnames(s)
f <- as.formula(paste(cn[1], '~', cn[2]))
boxplot(f, data=s)
Perhaps you should only provide your raster values as a vector and let the boxplot() function do the rest by:
boxplot(values(DEM) ~ values(Cluster), xlab="Cluster", ylab="Elevation")
Note that this will only work if both DEM and Cluster are exactly the same extent and resolution.
I am having trouble extracting values or a point from a multi band raster of class rasterStack or rasterBrick. 'extract' works well with the individual rasters but posts an error when applied to the rasterStack or brick.
> all.var
class : RasterBrick
dimensions : 89, 180, 16020, 34 (nrow, ncol, ncell, nlayers)
resolution : 2, 2 (x, y)
extent : -179, 181, -89, 89 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : period_max, pct_signif_periodmax, pct_coi_periodmax, pct_ispos_signif, events_pos_periodmax, events_neg_periodmax, events_pos_all, events_neg_all, maxpower_pos, maxpower_neg, maxpower_events_pos, maxpower_events_neg, maxpower_pos_norm, maxpower_neg_norm, maxpower_events_pos_norm, ...
> point
Lon Lat
1 166.2790 -10.2690
2 26.9000 -33.6000
3 153.6209 -28.7001
4 113.8333 -28.6833
5 153.6335 -28.6591
6 153.5836 -28.4643
7 32.6833 -27.5333
8 32.6880 -27.5260
9 32.6880 -27.5260
10 32.6880 -27.5260
> point.extract<-extract(all.var, point, buffer=50000,na.rm=TRUE,fun=mean)
Error in apply(x, 2, fun2) : dim(X) must have a positive length
This works with individual rasters but fails with stack/brick and elicits an error only when I use a buffer argument.
Here is a working R example that illustrates the error:
library(raster)
b <- brick(nrow=89, ncol=180, nl=34, xmn=-179, xmx=181, ymn=-89, ymx=89, crs="+proj=longlat +datum=WGS84")
b[] <- 1
p <- matrix(c(166.2790,-10.2690,26.9000,-33.6000,153.6209,-28.7001,113.8333,-28.6833,153.6335,-28.6591,153.5836,-28.4643,32.6833,-27.5333,32.6880,-27.5260,32.6880,-27.5260,32.6880,-27.5260), ncol=2, byrow=TRUE)
v <- extract(b, p, buffer=50000, na.rm=TRUE, fun=mean)
That indeed gives the error you reported, probably due a bug in the raster package. Here is a work-around:
v <- extract(b, p, buffer=15000000)
# get the mean for each point (buffer) by layer
vv <- lapply(v, function(x) ifelse(is.matrix(x), colMeans(x, na.rm=TRUE), x))
# combine
do.call(rbind, vv)
I want writeRaster to write the RAT (raster attribute table) that I've built in R.
I'm running R 3.0.1, raster 2.1-49, and rgdal 0.8-10.
My input raster looks like this:
r <-raster("F:/test.img")
class : RasterLayer
dimensions : 3, 3, 9 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 347325, 347415, 4301655, 4301745 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : F:\test.img
names : test
values : 1, 19 (min, max)
I then build my attribute table:
r <- ratify(r)
rat <- levels(r)[[1]]
rat$Pixel_Values <- c(1, 7, 8, 9, 19)
rat$Class_Names <- c("A", "B", "C", "D", "E")
levels(r) <- rat
Which results in a raster with attributes:
r
# class : RasterLayer
# dimensions : 3, 3, 9 (nrow, ncol, ncell)
# resolution : 30, 30 (x, y)
# extent : 347325, 347415, 4301655, 4301745 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
# data source : F:\test.img
# names : test
# values : 1, 19 (min, max)
# attributes :
# ID Pixel_Values Class_Names
# 1 1 A
# 7 7 B
# 8 8 C
# 9 9 D
# 19 19 E
I then attempt to write my raster together with its RAT:
ratRaster <- "F:/testRat.img"
writeRaster(r, filename=ratRaster, datatype="INT1U", RAT=TRUE, progress="window", overwrite=TRUE)
But when I read it back into R, it becomes apparent that the attributes did not persist:
r2 <- raster(ratRaster)
r2
# class : RasterLayer
# dimensions : 3, 3, 9 (nrow, ncol, ncell)
# resolution : 30, 30 (x, y)
# extent : 347325, 347415, 4301655, 4301745 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
# data source : F:\testRat.img
# names : testRat
# values : 1, 19 (min, max)
It would be quick and awesome to build RATs in R. How can I create and export the raster and keep the RAT?
Note that if you use raster's native .grd format (see doc, section 3.3) , the RAT table will be saved:
library(raster)
r <- raster(nrows=5, ncols=5)
r[] <- rep(1:5, 5)
r <- ratify(r)
rat <- levels(r)[[1]]
rat$Pixel_Values <- 1:5
rat$Class_Names <- c("A", "B", "C", "D", "E")
levels(r) <- rat
r
writeRaster(r, filename="raster_rat.grd")
Now re-open:
r2 <- raster("raster_rat.grd")
r2
You could always write the RAT as a csv file, then join that data later.
Write your raster as you specified:
writeRaster(r, filename=ratRaster, datatype="INT1U", RAT=TRUE, progress="window", overwrite=TRUE)
Write the attribute data/table/RAT as a .csv file:
write.csv(rat, file="C:\\merp\\rat.csv", row.names = F)
Then you can join this data in another program later.
For example, if exporting from R to ArcMap, write the raster to disk, write the attribute data as csv file, then join your RAT to the raster using the Add Join tool in ArcMap.
Reading the definition of writeRaster writing the RAT is clearly not implemented, at least for the native and the GTif format. Actually, one of the first things done is to remove the RAT. Not too surprising given the comments in ratify() help:
The functions documented here are
mainly available such that files with a RAT can be read and
processed; currently there is not too much further support.
From and to R you can always use
save(r,file=ratRaster)
and then
load(ratRaster)
It keeps everything.
I am having trouble with the extract function in the raster package. The raster is not empty, but when I perform the extract function all the values come back as NAs. I can plot the points over the raster fine and they show up in the same location.
library(dismo)
library(raster)
#Import CSV File
file <- paste("C:/Michelle/Michelle/R/CuskPA_Sept12_2013_1.csv", sep=" ")
#read file
cusk <- read.table(file, header=TRUE, sep=',')
cusks<- subset(cusks, SlongDD!=0 & SlatDD!=0)
cuskll <-cusks[,24:25]
#import raster
salvar <- raster("C:/Michelle/Michelle/R/Variables/salvar")
ext <-extent(-67.6, -64.9, 41.0, 44.7453)
salvarc <-crop(salvar, ext)
#extract from raster
psalvar <- extract(salvarc, cuskll)
This is what I get when I'm finished the extraction
head(psalvar)
[1] NA NA NA NA NA NA
summary(psalvar)
Mode NA's
logical 3859
The raster does not show up as empty.
> salvar
class : RasterLayer
dimensions : 334, 240, 80160 (nrow, ncol, ncell)
resolution : 0.01121539, 0.01121539 (x, y)
extent : -67.59662, -64.90493, 41.00048, 44.74642 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs
data source : in memory
names : salvar
values : 0.01655413, 2.137321 (min, max)
Here is an example of the lat/longs in the file
head(cuskll)
SlatDD SlongDD
1 44.41533 -66.07883
2 44.41167 -66.07733
3 44.44883 -66.07433
4 44.47067 -66.01217
5 44.47050 -66.01183
6 44.47633 -66.01450
Put longitude first and latitude second