R sf::st_convex_hull() потеря класса sf для данных с несколькими группами

#r #sf

#r #sf

Вопрос:

Я пытаюсь создать минимальный выпуклый многоугольник на 95%, используя sf в R. Мой код работает нормально, пока я группирую свои данные только по 1 переменной, но когда я группирую по двум переменным, результат теряет свой класс sf и вместо этого становится grouped_df .

Вот игрушечный набор данных в качестве примера

 library(dplyr) 
set.seed(12)
toy <- tibble::tibble(
    ID = rep(c(1,2), each = 10),
    year = rep(c(1,2), 10),
    lat = runif(20, 1, 10),
    long = runif(20, 1, 10)
  ) %>%
    sf::st_as_sf(., coords = c("long", "lat")) 
toy %>%
  group_by(ID) %>% 
  summarize(.groups = "keep") %>% 
  mutate(cent = sf::st_centroid(geometry)) %>%
  sf::st_cast(to = "POINT") %>%  
  mutate(dist = sf::st_distance(geometry, cent, by_element = TRUE)) %>% 
  filter(dist <= quantile(dist, .95)) %>% 
  summarize()  %>%
  sf::st_convex_hull() %>%
  class()
  

Это дает желаемый результат. Но когда я пытаюсь сгруппировать по двум переменным, результат теряет класс sf.

 toy %>%
  group_by(ID, year) %>% 
  summarize(.groups = "keep") %>% 
  mutate(cent = sf::st_centroid(geometry)) %>%
  sf::st_cast(to = "POINT") %>%  
  mutate(dist = sf::st_distance(geometry, cent, by_element = TRUE)) %>% 
  filter(dist <= quantile(dist, .95)) %>% 
  summarize()  %>%
  sf::st_convex_hull() %>%
  class
  

Есть ли что-то в моем коде, что мешает мне группировать по двум переменным?

Ответ №1:

Это потому, что второе обобщение перегруппировывается по идентификатору. Вам нужен .groups = "keeps" там, чтобы передать ту же группировку, а затем преобразовать обратно в объект sf. В качестве альтернативы вы могли бы создать группирующую переменную mutate(grp = paste0(ID, year)) и выполнить group_by(grp) .

 toy %>%
  group_by(ID, year) %>% 
  summarize(.groups = "keep") %>% 
  mutate(cent = sf::st_centroid(geometry)) %>%
  sf::st_cast(to = "POINT") %>%  
  mutate(dist = sf::st_distance(geometry, cent, by_element = TRUE)) %>% 
  filter(dist <= quantile(dist, .95)) %>% 
  summarize(.groups = "keep")  %>%
  sf::st_convex_hull() %>%
  st_sf()
  

Комментарии:

1. Спасибо! .groups = «keep» работает в сочетании с st_sf() в конце. Но почему он вообще теряет свой класс sf?