I wrote a function to extract values from ncdf files, as shown below:
precresults <- function(x){
library(magrittr)
library(ncdf4)
library(raster)
library(ncdf.tools)
##library(ncf)
re1 <- brick(nl1a[x])
re <- extract(re1,zuobiao)
####zuobiao stands for the coordinate of the targeted sites
###extract(zuobiao)
return(re)
}
###precresults(20)
precresults11 <- lapply(1:420, precresults)
"lapply" function is used to extract values for multiple site.
However, an error occurs:
Error in UseMethod("extract_") : no applicable method for
'extract_' applied to an object of class "c('RasterBrick', 'Raster',
'RasterStackBrick', 'BasicRaster')"
How can we solve such error?
I think Roman is correct, magrittr::extract is masking raster::extract. In the example provided you do not use magrittr, but you may use it elsewhere, so use raster::extract rather then extract. Your function could be rewritten as:
library(raster)
precresults <- function(x){
re1 <- brick(nl1a[x])
raster::extract(re1, zuobiao)
}
precresults11 <- lapply(1:420, precresults)
Or like this:
library(raster)
x <- matrix(nrow=length(zuobiao), ncol=420)
for (i in 1:420) {
re1 <- brick(nl1a[i])
x[,i] <- raster::extract(re1, zuobiao)
}
Related
I have 90 rasters that I need to clip and ressample to match my template raster. Is there a way for me to "automize this"? (i.e., only have to run the process once, so that I can, for instance, leave it running overnight)
I know that the answer is probably a "loop", but I'm not sure how to do it because each original file has a different name and the final product needs to have that same name, but end in "_final.asc"
This is the code I've been using:
library(raster)
#load original world raster (the one to be processed)
mau <- raster("PATH/name_of_the_raster.asc")
#load bounding box raster made by me (to clip the original and therefore make the next steps easier)
rastergrande <- raster("PATH")
#clip original raster by bounding box raster
intermedio <- crop(mau, rastergrande)
#load my template raster (the one that has the extent and cell size I want)
template <- raster("PATH")
#resample raster to template parameters
novoraster <- resample(intermedio, template, "bilinear")
#assign NA's to where template is NA
values(novoraster)[is.na(values(template))] <- NA
#Export to ascii
writeRaster(novoraster, "PATH/name_of_the_raster_final.asc", overwrite=TRUE)
Variations of this question have been asked a number of times. Here is one example
The general approach can be to get a vector with all your filenames, typically with list.files, and use that to make a vector of output filenames by changing the names or the path. Something like this:
input <- list.files(path=".", pattern="asc$", full.names=TRUE)
output <- gsub(".tif", "_out.tif", input)
Or change the folder
output <- gsub("this/path", "that/path", input)
And then use a loop
for (i in 1:length(input)) {
# read input[i]
# write output[i]
}
A working minimal example (using a single file):
library(raster)
input <- system.file("external/test.grd", package="raster")
# write to current working directory, but with asc extensions
output <- gsub(".grd", ".asc", basename(input))
for (i in 1:length(input)) {
r <- raster(input[i])
writeRaster(r, output[i], overwrite=TRUE)
}
Also, not directly related to your question, but this:
values(novoraster)[is.na(values(template))] <- NA
Should be
novoraster <- mask(novoraster, template)
You can use lapply. You would need a vector of file names, maybe with
fn_list <- list.files("PATH", pattern="asc$")
Your workhorse function could look like
one_file <- function(fn, template, rastergrande) {
mau <- raster(fn)
intermedio <- crop(mau, rastergrande)
novoraster <- resample(intermedio, template, "bilinear")
values(novoraster)[is.na(values(template))] <- NA
fn_out <- gsub("asc$", "_final.asc", fn)
writeRaster(novoraster, fn_out)
}
You can then apply one_file on fn_list:
library(raster)
library(usdm)
library(ggplot2)
library(rgdal)
rastergrande <- raster("PATH")
template <- raster("PATH")
lapply(fn_list, one_file, template=templ, rastergrande=rastergrande)
By the way, take a look at the terra package: https://www.youtube.com/watch?v=O8V4QJ13Gjc
Here you can work with a for loop or apply (lapply and mapply)
file_names <- list.files("PATH/", pattern = ".tif")
r_list <- lapply(file_names,raster)
rastergrande <- raster("PATH")
template <- raster("PATH")
intermedio <- list()
novoraster <- list()
Creating a vector with rasters names
rasternames <- c("name1","name2" ...)
For loop to process all rasters
for(i in 1:length(file_names){
intermedio[[i]] <- crop(r_list[[i]], rastergrande)
novoraster[[i]] <- resample(intermedio[[i]], template, "bilinear")
values(novoraster[[i]])[is.na(values(template))] <- NA
writeRaster(novoraster[[i]], paste0("PATH/", rasternames[i], ".asc"), overwrite=TRUE)
}
Here is my sample code:
library(haven)
community_surveys <- read_sav("community_surveys.sav")
diss_data <- as.data.frame(community_surveys)
diss_data$FOC_1 <- as.factor(diss_data$FOC_1)
diss_data$DR_1 <- as.factor(diss_data$DR_1)
diss_data$IR_1 <- as.factor(diss_data$IR_1)
diss_data$HAITI <- as.factor(diss_data$HAITI)
diss_data$TREATMENT <- as.factor(diss_data$TREATMENT)
library(mice)
mice(diss_data, maxit = 10, m = 10)
I get this error below:
Error: `t.haven_labelled()` not supported
As far as the level of comprehension, I am a newbie R user with a couple intro classes and some reading under my belt. Any assistance much appreciated.
Labelled data from haven leads to all sorts of weird problems. You could try one of the following:
If your data should be numeric: sapply(diss_data, haven::zap_labels)
For factors: sapply(diss_data, haven::as_factor)
You could also just try to replace the command in your code like this:
diss_data$FOC_1 <- haven::as_factor(diss_data$FOC_1)
diss_data$DR_1 <- haven::as_factor(diss_data$DR_1)
diss_data$IR_1 <- haven::as_factor(diss_data$IR_1)
diss_data$HAITI <- haven::as_factor(diss_data$HAITI)
diss_data$TREATMENT <- haven::as_factor(diss_data$TREATMENT)
You could remove value labels by using remove_val_labels() from labelled library.
I was trying to convert a dataset from netcdf to csv format using R.
although I have installed 'raster and 'netcdf4' in R.
but still it doesn't find nc.brick.
rm(list=ls())
library(raster)
library(ncdf4)
nc.brick <- brick(file.choose)
dim(nc.brick)
nc.df <- as.data.frame(nc.brick[[1]],xy=T)
head(nc.df)
write.csv(nc.df,file.choose())
test <- read.csv(file.choose())
Can you see the difference between your usage of file.choose in these two lines:
nc.brick <- brick(file.choose)
write.csv(nc.df,file.choose())
there's your problem.
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)
I have an object that I have created using the as.ts function in R, and now I would like a simple way to transform one of the variables and add it to the same ts object. So, for example
tsMloa <- ts(read.dta("http://www.stata-press.com/data/r12/mloa.dta"), frequency=12, start=1959)
tsMloa[, "meanLog"] <- tsMloa[,"log"] - mean(tsMloa[,"log"])
gives me a subscript out of bounds error. How can I get around this?
Firstly, you ought to consider adding require(foreign) to your example code, as it's necessary to run your code.
I don't know anything about *.dta files or their formatting, but i can tell you that if you'd like to work with time series in R, you'd do well to look into the zoo and xts family of functions.
With that in mind, try the following:
require(xts)
require(foreign)
tsMloa <- ts(read.dta("http://www.stata-press.com/data/r12/mloa.dta"), frequency=12, start=1959)
tt <- seq(as.Date("1959-01-01"), as.Date("1990-12-01"), by='mon')
tsMloa_x <- xts(unclass(tsMloa)[,1:3], order.by=tt)
tsMloa_x$meanLog <- tsMloa_x$log - mean(tsMloa_x$log)
That should do what you are looking for -- and it gives you a reason to look into the very good packages.
Doing it with zoo -- plus i've created a function to turn your integers into months.
require(foreign)
require(zoo)
Mloa <- read.dta("http://www.stata-press.com/data/r12/mloa.dta"), frequency=12, start=1959)
intToMonth <- function(intMonth, origin = "1960-01-01"){
dd <- as.POSIXlt(origin)
ddVec <- rep(dd, length(intMonth))
ddVec$mon <- ddVec$mon + intMonth%%12
ddVec$year <- ddVec$year + intMonth%/%12
ddRet <- as.Date(ddVec)
return(ddRet)
}
dateString <- intToMonth(Mloa[, 'tm'])
zMloa <- zoo(Mloa[, -2], dateString)
zMloa$meanLog <- zMloa$log - mean(zMloa$log)
As i see it, your problem is with converting the timestamps in the source file to something R understands and can work with. I found this part of adapting to R especially tricky.
The above function will take your month-integers, and turn them into a Date object. The resultant output will work with both zoo and xts as the order.by argument.
If you need to change the origin date, just supply the second argument to the function -- i.e. otherDateString <- intToMonth(timeInts, "2011-01-01").