TJeff
TJeff

Reputation: 39

How do I create multiple rasters for each unique value in a dataframe?

I have a dataframe containing lat, long, species name, iucn_status, class, as per below...

`1  -0.25   -80.75  Axoclinus cocoensis VU  Actinopterygii
2   -0.75   -80.75  Axoclinus cocoensis VU  Actinopterygii
3   -8.75   -172.25 Axoclinus cocoensis VU  Actinopterygii
4   -9.25   -171.25 Axoclinus cocoensis VU  Actinopterygii
5   -9.25   -171.75 Axoclinus cocoensis VU  Actinopterygii
6   -13.75  -171.25 Axoclinus cocoensis VU  Actinopterygii` #3,500,000 rows total

What I would like to do is create a raster for each species containing it's distribution (the above d.f contains 516 species) and then convert/export each raster as an ASCII (.asc) file. I have got bits of code but can't seem to tally them together properly...

`ids=unique(aqua_trim$Species) #I want to name each raster the species name
all_rasters <- list()
all_dfs <- list()
for (i in ids){ 
loopraster <- tempraster #tempraster is the empty raster of desired extent and resolution
tablepoints<-table(cellFromXY(tempraster, subset(aqua_trim, id==i)))  
dfpoints<-as.data.frame(tablepoints) 
dfpoints$Freq<-dfpoints$Freq/sum(dfpoints$Freq)
loopraster[as.numeric(names(tablepoints))]<-tablepoints
all_rasters[[i]] <- loopraster
all_dfs[[i]] <- dfpoints
print(i)
}`

The above worked to create a list of rasters, but they were all empty, after editing it, it's now giving an error, Error in id == i : comparison (1) is possible only for atomic and list types

Previous questions and code I'm trying to adapt:

Writing a loop to create multiple dataframes and rasters from a SpatialPointsDataFrame

How to make raster from unique values?

I won't put all the attempts I've made here or errors but any help would be greatly appreciated.

Upvotes: 0

Views: 459

Answers (1)

Robert Hijmans
Robert Hijmans

Reputation: 47591

Here is a minimal self-contained, reproducible example.

Example data

library(raster)
r <- raster(system.file("external/rlogo.grd", package="raster"))
r <- aggregate(raster(r), 15)  # empty raster of desired properties
xy <- matrix(c(48, 48, 48, 53, 50, 46, 54, 70, 84, 85, 74, 84, 95, 85, 
      66, 42, 26, 4, 19, 17, 7, 14, 26, 29, 39, 45, 51, 56, 46, 38, 31, 
      22, 34, 60, 70, 73, 63, 46, 43, 28), ncol=2)

Make a raster with number of observations per cell

rsp <- rasterize(xy, r, fun="count")

Next I show how to do this in a loop. First create three species.

spdata <- rbind(data.frame(sp = "bird", xy), 
             data.frame(sp="mammal", xy / 2),
             data.frame(sp="lizard", sqrt(xy)))

And on to the loop. First get the species names and create an empty list for the results. Then loop over the species names.

spp <- unique(spdata$sp)
result <- list()
for (i in 1:length(spp)) {
   # get the coordinates for species i
   spi <- spdata[spdata$sp == spp[i], 2:3]      
   result[[i]] <- rasterize(spi, r, fun="count")
 }  

Have a look

s <- stack(result)
plot(s)

To instead save a file for each species, you can change the loop like this, here using the ascii format as requested

for (i in 1:length(spp)) {
   spi <- spdata[spdata$sp == spp[i], ]      
   fname <- paste0(spp[i], ".asc")
   x <- rasterize(spi[,2:3], r, fun="count", filename=fname)
 } 

Upvotes: 1

Related Questions