При попытке заменить набор точек в столбце sf sfc я получаю несколько видов ошибок. Я пробовал несколько вещей, используя как dplyr, так и базовые методы, каждый из которых приводил к ошибкам. Единственное решение, которое я нашел, - полностью заменить столбец геометрии sfc, что кажется неоптимальным решением.
В моем конкретном примере у меня есть четыре точки, две из которых имеют одинаковый идентификатор в столбце «а». Я пытаюсь обновить геометрию для точек с идентификатором 17 от (11,12) до (12,13). В качестве иллюстрации я также пытаюсь обновить геометрию для ID 16, обновив ее с (0,1) до (5,6).
library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
geom = st_sfc(st_point(c(0,1)), st_point(c(0,1)), st_point(c(11,12)),st_point(c(11,12)))
a_col = c(15,16,17,17)
sf = st_sf(a = a_col, geometry = geom)
#Approach 1. doesn't work for a== 17
sf2 <-
sf %>%
mutate(geometry = case_when(a==17 ~ st_sfc(st_point(c(12,13))),
TRUE ~ geometry))
#> Error in mutate_impl(.data, dots): Evaluation error: must be sfc_GEOMETRY/sfc, not sfc_POINT/sfc.
#Approach 1 also doesn't work for a==16
sf2 <-
sf %>%
mutate(geometry = case_when(a==16 ~ st_sfc(st_point(c(5,6))),
TRUE ~ geometry))
#> Error in mutate_impl(.data, dots): Evaluation error: must be sfc_GEOMETRY/sfc, not sfc_POINT/sfc.
#Approach 2. This works when column a value is unique...
sf2 <- sf
st_geometry(sf2[sf2$a ==16,]) <- st_sfc(st_point(c(5,6)))
#but fails when column a value is not unique.
sf2 <- sf
st_geometry(sf2[sf2$a ==17,]) <- st_sfc(st_point(c(12,13)))
#> Error in `st_geometry<-.sf`(`*tmp*`, value = structure(list(structure(c(12, : nrow(x) == length(value) is not TRUE
#Approach 3. could wholesale replace the geometry sfc column, but seems like there's a better way
geom2 <- geom
geom2[sf$a==17] <- st_point(c(12,13))
sf2 = st_sf(a = a_col, geometry = geom2)
Как вы можете видеть, Подход 1 (dplyr :: case_when и dplyr :: mutate) терпит неудачу - это был бы мой предпочтительный подход, так как я работаю в стиле tidyverse и имею другие условия и логику для применения в этой конкретной задаче , Подход 2 (замена в st_geometry) работает, когда идентификатор является уникальным, но не работает, когда его нет. Подход 3 работает, но из-за времени обработки, читабельности кода и других причин не будет предпочтительным (примечание: получено из этого вопроса SO Замените геометрии из списка в sf )
Любые рекомендуемые решения, особенно в соответствии с подходом 1 - dplyr :: case_when?