0

I have a data.frame with a column called geo. In this column, there are lists with coordinates that represent a bounding box. I would like to grab the coordinates that are inside each list and calculate the centroid for each bbox (new column with centroid as a point).

dput:

structure(list(full_name = c("Karlsruhe, Deutschland", "Volksparkstadion", 
"Hamburg, Deutschland"), country_code = c("DE", "DE", "DE"), 
    place_type = c("city", "poi", "city"), name = c("Karlsruhe", 
    "Volksparkstadion", "Hamburg"), country = c("Deutschland", 
    "Deutschland", "Deutschland"), id = c("5b146bf0b819f1af", 
    "0fc3a3fa5494c000", "5bcd72da50f0ee77"), geo = list(bbox = list(
        8.2773, 48.9405, 8.5418, 49.0914), bbox = list(9.8986, 
        53.5871, 9.8986, 53.5871), bbox = list(8.4202, 53.3951, 
        10.3252, 53.9647))), row.names = c(2L, 5L, 8L), class = "data.frame")

1 Answer 1

0

You can iterate the list contained in the data.frame using lapply. I am nesting a bunch of functions st_coordinates(st_centroid(st_as_sfc(st_bbox())), which you could plausibly pipe (eg., magrittr %>% or native R |>), to return the centroids then using do.call on the resulting list to create a data.frame that can be added back to your data.

library(sf)

dat <- structure(list(full_name = c("Karlsruhe, Deutschland", "Volksparkstadion", 
"Hamburg, Deutschland"), country_code = c("DE", "DE", "DE"), 
    place_type = c("city", "poi", "city"), name = c("Karlsruhe", 
    "Volksparkstadion", "Hamburg"), country = c("Deutschland", 
    "Deutschland", "Deutschland"), id = c("5b146bf0b819f1af", 
    "0fc3a3fa5494c000", "5bcd72da50f0ee77"), geo = list(bbox = list(
        8.2773, 48.9405, 8.5418, 49.0914), bbox = list(9.8986, 
        53.5871, 9.8986, 53.5871), bbox = list(8.4202, 53.3951, 
        10.3252, 53.9647))), row.names = c(2L, 5L, 8L), class = "data.frame")
        
( centroid <- lapply(dat$geo, function(x) {
  st_coordinates(st_centroid(st_as_sfc(st_bbox(c(xmin=x[[1]], 
      xmax=x[[2]], ymin=x[[3]], ymax=x[[4]])))))
}) )

( dat <- data.frame(dat, do.call('rbind', centroid)) )

Piped version (may be more understandable to tidyverse users) of the lapply step using the R native pipe so, not very tidy.

centroid <- lapply(dat$geo, function(x) {
  st_bbox(c(xmin=x[[1]], xmax=x[[2]], 
        ymin=x[[3]], ymax=x[[4]])) |> 
    st_as_sfc() |>
      st_centroid() |> 
        st_coordinates() 
})  

Your Answer

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

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