1

This question is connected to: How to create a regular, square grid, and find centroid by factors using R

I have a data frame which have three columns: (1) the "scientificName" column containing some species names; and its respective (2) longitude and (3) latitude values.

head(data)
            scientificName         x          y
1  Aceratobasis_cornicauda -40.56560 -19.901400
2  Aceratobasis_macilenta  -49.00881 -25.516721
3  Aceratobasis_nathaliae  -53.99830 -26.505600
4  Amazoneura_ephippigera  -73.18583  -4.372778
5  Amazoneura_ephippigera  -64.68917  -3.512500
6  Amazoneura_juruaensis   -72.90000  -7.618056

In the above-mentioned question, I managed to find the centroid of my factors, and create a square grid over my data by:

data <- read.table("clipboard", header=T)
centroids <- data %>%
  group_by(scientificName) %>%
  summarize(centroid_x = mean(x),
            centroid_y = mean(y))
sp_centroids <- SpatialPoints(centroids[, c("centroid_x", "centroid_y")], 
                              proj4string = CRS("+proj=longlat +datum=WGS84"))

scientific_names <- centroids$scientificName
attr(sp_centroids, "scientificName") <- scientific_names

centroids_sf <- st_as_sf(centroids,
                    coords = c("centroid_x", "centroid_y"),
                    crs = "+proj=longlat +datum=WGS84")

grid_sf <- centroids_sf %>%
  st_bbox() %>%
  st_as_sfc() %>%
  st_make_grid(cellsize = c(0.5, 0.5), 
               crs = "+proj=longlat +datum=WGS84",
               square = T) 

centroids_sf <- st_transform(centroids_sf, st_crs(grid_sf))|> st_as_sf()

centroids_sf consists in a list of the same length as my factors. However, I'm not being able to properly convert my centroids_sf to a spatial object so I can use it in raster(). I tried to intersect it with my centroids by:

grid_subset <- grid[st_intersects(centroids_sf, grid_sf) |> unlist(), ]

By I keep getting the following error:

Error in grid[unlist(st_intersects(centroids_sf, grid_sf)), ] :
object of type 'closure' is not subsettable

In sum, I want to intersect centroids_sf with grid_sf so I can use raster to extract bio-climatic variables from this subset.

Here is part of my session info:

other attached packages: 1 raster_3.5-21 dplyr_1.0.10 sp_1.5-0 sf_1.0-9

4
  • Maybe I'm missing something, but it seems you are making this more complicated than it needs to be. You got some good advice from @Spacedman in the earlier post. Can you explain what you want to achieve? (not how you're trying to do it). You have point locations of species occurence for a few species. What analysis do you want to do?
    – Micha
    Jan 31, 2023 at 15:30
  • I want to know which cells in my grid contain centroids, so I can use them to extract bio-climatic variables. My apologies if I wasn't clear enough. Jan 31, 2023 at 16:13
  • Can I ask why you don't extract bio-climatic variables for all species points, then do some sort of point pattern analysis? or spatial autocorrelation? I don't see what is the purpose of this grid. But if you have your answer, feel free to ignore ;-)
    – Micha
    Feb 1, 2023 at 16:50
  • I extracted the centroid to handle bias associated with within-species sampling size due to study design and/or species biology (rare, common). Initially I built a model with a spatial autocorrelation structure, but it didn't effectively address these issues (at least I think so). Feb 1, 2023 at 23:13

3 Answers 3

1

Read the error message:

Error in grid[unlist(st_intersects(centroids_sf, grid_sf)), ] :
object of type 'closure' is not subsettable

What are you trying to subset in this code? The object grid. Why is it not subsettable? Because its a "closure", or function.

You don't show us what grid is in your code, so I assume you've not defined it at all, and its actually using the grid function in the base graphics package.

Maybe you mean grid_sf[...]?

Lessons: read the error message, and break down the problem.

0

The problem was in:

grid_sf <- centroids_sf %>%
  st_bbox() %>%
  st_as_sfc() %>%
  st_make_grid(cellsize = c(0.5, 0.5), 
               crs = "+proj=longlat +datum=WGS84",
               square = T) 

For some reason st_as_sfc() wasn't transforming my data in a readable sf. By using |> st_as_sf() instead I was able to extract mean sampling variables from my grid subset.

grid_sf <- centroids_sf %>%
  st_bbox() %>%
  st_make_grid(cellsize = c(0.5, 0.5), 
               crs = "+proj=longlat +datum=WGS84",
               square = T)|> st_as_sf()
0

You describe your goal (partly on the comments) as extracting climate data from rasters using the centroids of sets of locations by species. If that is your goal, your solution does not make much sense.

What you could do is:

Get the centroids

centroids <- aggregate(data[, c("x", "y")], 
          data[, "scientificName",drop=FALSE], mean, na.rm=TRUE)

Extract climate data

library(terra)
x <- rast("your files")
e <- extract(x, centroids)

If you wanted to create a raster based on the extent of these centroids (but why?) you could do

v <- vect(centroids, crs="+proj=longlat")
r <- rast(v)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.