rkernel-densitytmapextent

Creating multiple density maps with same extent


I am trying to create density maps (rasters) from points using the smooth_map function from the tmaptools package. I would like to create one raster for each factor level of a variable (var) in my dataframe (df). All rasters should have the same extent, given by a shapefile (study_area). I want to stack them and subsequently plot them using levelplot.

However, all rasters returned by the function have slightly different extents. I could not figure out how to create the density maps with same extents. This is the code:

library(tmaptools) 
library(rgdal)
library(sf)
library(raster)

##reproducible example of dataframe
df<-setNames(data.frame(matrix(ncol = 3, nrow = 7)), c("longitude", "latitude", "var"))

df$longitude<-c(-53.30002, -50.47749, -55.85561, -57.88447, -55.83864, -58.84610, -57.49215)
df$latitude<-c(-13.037530,  -13.023480, -13.416200, -13.659120, -12.758670, -13.114460, -14.622520)
df$var<-c("A", "A", "A", "A", "B", "B", "B")

## convert var to factor
df$var<-as.factor(df$var)

##read shapefile of Mato Grosso, Brazil 
## shapefile can be downloaded from e.g. https://geo.nyu.edu/catalog/stanford-vw409fv3488
study_area<-readOGR("shape_MT.shp", layer="shape_MT") #will load the shapefile 

#create empty stack
s <- stack()

#loop over factor levels
for (i in levels(df$var)) { 
  a<-subset(df, df$var==i)
  my.sf.point <- st_as_sf(x = a, coords = c("longitude", "latitude"),crs = "+proj=longlat  +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
  density_map <- smooth_map(my.sf.point, cover = study_area) 
  r<-density_map$raster
  print(extent(r))
  s <- stack(s,r)
}

I get the following error message:

Error in compareRaster(x) : different extent

Any idea on how to solve this?


Solution

  • Perhaps this works for you:

    ## convert var to factor
    df$var<-as.factor(df$var)
    
    ## read shapefile of Mato Grosso, Brazil 
    ## shapefile can be downloaded from e.g. https://geo.nyu.edu/catalog/stanford-vw409fv3488
    study_area<-readOGR("....", layer="...") 
    

    It will also work with your own crs but perhaps ESRI:102033 South_America_Albers_Equal_Area_Conic looks like a better option here (or something similar):

    crs.laea <- CRS("+proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs")
    study_area <- spTransform(study_area, CRS = crs.laea)
    
    #create empty stack
    s <- list()
    
    #loop over factor levels
    for (i in levels(df$var)) { 
      a<-subset(df, df$var==i)
      my.sf.point <- st_as_sf(x = a, coords = c("longitude", "latitude"), crs = "+proj=longlat +ellps=aust_SA +no_defs")
    
      #reprojecting to ESRI:102033 South_America_Albers_Equal_Area_Conic
      my.sf.point <- st_transform(my.sf.point, 102033)
      density_map <- smooth_map(my.sf.point, cover = study_area, nrow = 514, ncol = 510) 
      r<-density_map$raster
    
      extent(r) <- c(-175916.2, 1048374, 1610251, 2845008) # extent of the study area
      plot(r)
    
      s[[i]] <- r
    }
    
    s[["A"]] <- resample(s[["A"]],s[["B"]],method='bilinear')
    
    stack(s)