为什么对 sf 中每个特征差异的不同方法会导致不同的绘图缩放?
Why do different approaches to per-feature differences in sf cause different plot zoom?
我觉得我似乎缺乏直觉,无法始终了解 sf
对象将如何与 tidyverse
工具交互,尤其是 dplyr
。这是一个例子。我们正在寻找两个点缓冲区,然后减去较小的缓冲区,以便在每个点周围留下 ring/annulus。我提供了两种方法。
首先断开几何列,使用 map2
获取环,然后将其固定回原始 sf
数据框。这种方法是有道理的;我知道所有部分是如何工作的,但感觉不 "tidy" 或整洁,因为我们创建了中间对象,我们必须手动替换 crs
,感觉好像很容易将几何形状不匹配到属性。
第二种方法是我想出的,试图将它保存在一个管道中。在这里,我希望 group_by
和 mutate
可以工作,某种程度上,管理至少到 运行 没有错误,并且似乎创建了正确的圆环,但有些东西导致了 plot 方法放大远。我也不知道这两种方法的实际作用是否还有其他差异。
编辑:不仅仅是绘图缩放不同,st_bbox
的结果也因某种原因而不同。然而,环似乎仍然以点为中心,在 mapview::mapview()
中看起来是一样的。还包括会话信息,我已更新到 R 3.4.4、sf
0.6-1、tidyverse
1.2.1。我会更新其他所有内容,看看会发生什么。
library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
set.seed(12345)
points = map2(runif(50, -10, 10), runif(50, -10, 10), ~ st_point(c(.x, .y))) %>%
st_sfc(crs = 4326) %>%
st_transform(3857)
sf_pts = st_sf(val = 1:50, geometry = points)
ring1 = st_buffer(points, 50000)
ring2 = st_buffer(points, 100000)
sep_rings = st_sfc(map2(ring2, ring1, ~ st_difference(.x, .y)), crs = 3857)
sf_opt1 <- sf_pts %>%
st_set_geometry(sep_rings)
plot(sf_opt1)
plot(sf_opt1$geometry)
plot(sf_pts$geometry, add = T)
sf_opt2 <- sf_pts %>%
mutate(
ring1 = st_buffer(geometry, 50000),
ring2 = st_buffer(geometry, 100000)
) %>%
rowid_to_column() %>%
group_by(rowid) %>%
mutate(geometry = st_difference(ring2, ring1)) %>%
ungroup() %>%
select(val)
plot(sf_opt2)
plot(sf_opt2$geometry)
plot(sf_pts$geometry, add = T)
st_bbox(sf_opt1)
#> xmin ymin xmax ymax
#> -1210664 -1199345 1190345 1187217
st_bbox(sf_opt2)
#> xmin ymin xmax ymax
#> 391818.2 938652.3 591818.2 1138652.3
由 reprex package (v0.2.0) 创建于 2018-04-10。
devtools::session_info()
#> Session info -------------------------------------------------------------
#> setting value
#> version R version 3.4.4 (2018-03-15)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United Kingdom.1252
#> tz America/Los_Angeles
#> date 2018-04-10
#> Packages -----------------------------------------------------------------
#> package * version date source
#> assertthat 0.2.0 2017-04-11 CRAN (R 3.4.1)
#> backports 1.1.2 2017-12-13 CRAN (R 3.4.3)
#> base * 3.4.4 2018-03-15 local
#> bindr 0.1.1 2018-03-13 CRAN (R 3.4.4)
#> bindrcpp * 0.2 2017-06-17 CRAN (R 3.4.1)
#> broom 0.4.3 2017-11-20 CRAN (R 3.4.2)
#> cellranger 1.1.0 2016-07-27 CRAN (R 3.4.1)
#> class 7.3-14 2015-08-30 CRAN (R 3.4.4)
#> classInt 0.1-24 2017-04-16 CRAN (R 3.4.2)
#> cli 1.0.0 2017-11-05 CRAN (R 3.4.2)
#> colorspace 1.3-2 2016-12-14 CRAN (R 3.4.1)
#> compiler 3.4.4 2018-03-15 local
#> crayon 1.3.4 2017-09-16 CRAN (R 3.4.2)
#> curl 3.1 2017-12-12 CRAN (R 3.4.3)
#> datasets * 3.4.4 2018-03-15 local
#> DBI 0.8 2018-03-02 CRAN (R 3.4.3)
#> devtools 1.13.5 2018-02-18 CRAN (R 3.4.3)
#> digest 0.6.15 2018-01-28 CRAN (R 3.4.3)
#> dplyr * 0.7.4 2017-09-28 CRAN (R 3.4.2)
#> e1071 1.6-8 2017-02-02 CRAN (R 3.4.2)
#> evaluate 0.10.1 2017-06-24 CRAN (R 3.4.2)
#> forcats * 0.3.0 2018-02-19 CRAN (R 3.4.3)
#> foreign 0.8-69 2017-06-22 CRAN (R 3.4.4)
#> ggplot2 * 2.2.1.9000 2018-03-28 Github (tidyverse/ggplot2@3c9c504)
#> glue 1.2.0 2017-10-29 CRAN (R 3.4.2)
#> graphics * 3.4.4 2018-03-15 local
#> grDevices * 3.4.4 2018-03-15 local
#> grid 3.4.4 2018-03-15 local
#> gtable 0.2.0 2016-02-26 CRAN (R 3.4.1)
#> haven 1.1.1 2018-01-18 CRAN (R 3.4.3)
#> hms 0.4.2 2018-03-10 CRAN (R 3.4.4)
#> htmltools 0.3.6 2017-04-28 CRAN (R 3.4.2)
#> httr 1.3.1 2017-08-20 CRAN (R 3.4.1)
#> jsonlite 1.5 2017-06-01 CRAN (R 3.4.1)
#> knitr 1.20 2018-02-20 CRAN (R 3.4.3)
#> lattice 0.20-35 2017-03-25 CRAN (R 3.4.4)
#> lazyeval 0.2.1 2017-10-29 CRAN (R 3.4.2)
#> lubridate 1.7.2 2018-02-06 CRAN (R 3.4.3)
#> magrittr 1.5 2014-11-22 CRAN (R 3.4.1)
#> memoise 1.1.0 2017-04-21 CRAN (R 3.4.2)
#> methods * 3.4.4 2018-03-15 local
#> mime 0.5 2016-07-07 CRAN (R 3.4.1)
#> mnormt 1.5-5 2016-10-15 CRAN (R 3.4.1)
#> modelr 0.1.1 2017-07-24 CRAN (R 3.4.1)
#> munsell 0.4.3 2016-02-13 CRAN (R 3.4.1)
#> nlme 3.1-131.1 2018-02-16 CRAN (R 3.4.4)
#> parallel 3.4.4 2018-03-15 local
#> pillar 1.2.1 2018-02-27 CRAN (R 3.4.3)
#> pkgconfig 2.0.1 2017-03-21 CRAN (R 3.4.1)
#> plyr 1.8.4 2016-06-08 CRAN (R 3.4.1)
#> psych 1.7.8 2017-09-09 CRAN (R 3.4.1)
#> purrr * 0.2.4 2017-10-18 CRAN (R 3.4.2)
#> R6 2.2.2 2017-06-17 CRAN (R 3.4.1)
#> Rcpp 0.12.16 2018-03-13 CRAN (R 3.4.4)
#> readr * 1.1.1 2017-05-16 CRAN (R 3.4.1)
#> readxl 1.0.0 2017-04-18 CRAN (R 3.4.1)
#> reshape2 1.4.3 2017-12-11 CRAN (R 3.4.3)
#> rlang 0.2.0.9001 2018-03-26 Github (r-lib/rlang@49d7a34)
#> rmarkdown 1.9 2018-03-01 CRAN (R 3.4.3)
#> rprojroot 1.3-2 2018-01-03 CRAN (R 3.4.3)
#> rvest 0.3.2 2016-06-17 CRAN (R 3.4.1)
#> scales 0.5.0.9000 2018-01-23 Github (hadley/scales@d767915)
#> sf * 0.6-1 2018-03-22 CRAN (R 3.4.4)
#> stats * 3.4.4 2018-03-15 local
#> stringi 1.1.7 2018-03-12 CRAN (R 3.4.4)
#> stringr * 1.3.0 2018-02-19 CRAN (R 3.4.3)
#> tibble * 1.4.2 2018-01-22 CRAN (R 3.4.3)
#> tidyr * 0.8.0 2018-01-29 CRAN (R 3.4.3)
#> tidyverse * 1.2.1 2017-11-14 CRAN (R 3.4.2)
#> tools 3.4.4 2018-03-15 local
#> udunits2 0.13 2016-11-17 CRAN (R 3.4.1)
#> units 0.5-1 2018-01-08 CRAN (R 3.4.3)
#> utils * 3.4.4 2018-03-15 local
#> withr 2.1.2 2018-03-26 Github (jimhester/withr@79d7b0d)
#> xml2 1.2.0 2018-01-24 CRAN (R 3.4.3)
#> yaml 2.1.18 2018-03-08 CRAN (R 3.4.3)
AFAICT,在您的示例中,您实际上是在每一行上编写一个循环(group/ungroup 围绕变异);通过在此循环中覆盖几何图形,您将获得最后一个特征的边界框,而不是整个几何图形列表列的边界框。问题是 st_difference 做所有成对差异,而不是行差异。您可以使用以下代码(需要来自 github 的 sf)获得逐行差异:
sf_opt2 <- sf_pts %>%
mutate(
ring1 = st_buffer(geometry, 50000),
ring2 = st_buffer(geometry, 100000)
) %>%
mutate(geometry = ring2 / ring1) %>%
select(val)
plot(sf_opt2)
我觉得我似乎缺乏直觉,无法始终了解 sf
对象将如何与 tidyverse
工具交互,尤其是 dplyr
。这是一个例子。我们正在寻找两个点缓冲区,然后减去较小的缓冲区,以便在每个点周围留下 ring/annulus。我提供了两种方法。
首先断开几何列,使用 map2
获取环,然后将其固定回原始 sf
数据框。这种方法是有道理的;我知道所有部分是如何工作的,但感觉不 "tidy" 或整洁,因为我们创建了中间对象,我们必须手动替换 crs
,感觉好像很容易将几何形状不匹配到属性。
第二种方法是我想出的,试图将它保存在一个管道中。在这里,我希望 group_by
和 mutate
可以工作,某种程度上,管理至少到 运行 没有错误,并且似乎创建了正确的圆环,但有些东西导致了 plot 方法放大远。我也不知道这两种方法的实际作用是否还有其他差异。
编辑:不仅仅是绘图缩放不同,st_bbox
的结果也因某种原因而不同。然而,环似乎仍然以点为中心,在 mapview::mapview()
中看起来是一样的。还包括会话信息,我已更新到 R 3.4.4、sf
0.6-1、tidyverse
1.2.1。我会更新其他所有内容,看看会发生什么。
library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
set.seed(12345)
points = map2(runif(50, -10, 10), runif(50, -10, 10), ~ st_point(c(.x, .y))) %>%
st_sfc(crs = 4326) %>%
st_transform(3857)
sf_pts = st_sf(val = 1:50, geometry = points)
ring1 = st_buffer(points, 50000)
ring2 = st_buffer(points, 100000)
sep_rings = st_sfc(map2(ring2, ring1, ~ st_difference(.x, .y)), crs = 3857)
sf_opt1 <- sf_pts %>%
st_set_geometry(sep_rings)
plot(sf_opt1)
plot(sf_opt1$geometry)
plot(sf_pts$geometry, add = T)
sf_opt2 <- sf_pts %>%
mutate(
ring1 = st_buffer(geometry, 50000),
ring2 = st_buffer(geometry, 100000)
) %>%
rowid_to_column() %>%
group_by(rowid) %>%
mutate(geometry = st_difference(ring2, ring1)) %>%
ungroup() %>%
select(val)
plot(sf_opt2)
plot(sf_opt2$geometry)
plot(sf_pts$geometry, add = T)
st_bbox(sf_opt1)
#> xmin ymin xmax ymax
#> -1210664 -1199345 1190345 1187217
st_bbox(sf_opt2)
#> xmin ymin xmax ymax
#> 391818.2 938652.3 591818.2 1138652.3
由 reprex package (v0.2.0) 创建于 2018-04-10。
devtools::session_info()
#> Session info -------------------------------------------------------------
#> setting value
#> version R version 3.4.4 (2018-03-15)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United Kingdom.1252
#> tz America/Los_Angeles
#> date 2018-04-10
#> Packages -----------------------------------------------------------------
#> package * version date source
#> assertthat 0.2.0 2017-04-11 CRAN (R 3.4.1)
#> backports 1.1.2 2017-12-13 CRAN (R 3.4.3)
#> base * 3.4.4 2018-03-15 local
#> bindr 0.1.1 2018-03-13 CRAN (R 3.4.4)
#> bindrcpp * 0.2 2017-06-17 CRAN (R 3.4.1)
#> broom 0.4.3 2017-11-20 CRAN (R 3.4.2)
#> cellranger 1.1.0 2016-07-27 CRAN (R 3.4.1)
#> class 7.3-14 2015-08-30 CRAN (R 3.4.4)
#> classInt 0.1-24 2017-04-16 CRAN (R 3.4.2)
#> cli 1.0.0 2017-11-05 CRAN (R 3.4.2)
#> colorspace 1.3-2 2016-12-14 CRAN (R 3.4.1)
#> compiler 3.4.4 2018-03-15 local
#> crayon 1.3.4 2017-09-16 CRAN (R 3.4.2)
#> curl 3.1 2017-12-12 CRAN (R 3.4.3)
#> datasets * 3.4.4 2018-03-15 local
#> DBI 0.8 2018-03-02 CRAN (R 3.4.3)
#> devtools 1.13.5 2018-02-18 CRAN (R 3.4.3)
#> digest 0.6.15 2018-01-28 CRAN (R 3.4.3)
#> dplyr * 0.7.4 2017-09-28 CRAN (R 3.4.2)
#> e1071 1.6-8 2017-02-02 CRAN (R 3.4.2)
#> evaluate 0.10.1 2017-06-24 CRAN (R 3.4.2)
#> forcats * 0.3.0 2018-02-19 CRAN (R 3.4.3)
#> foreign 0.8-69 2017-06-22 CRAN (R 3.4.4)
#> ggplot2 * 2.2.1.9000 2018-03-28 Github (tidyverse/ggplot2@3c9c504)
#> glue 1.2.0 2017-10-29 CRAN (R 3.4.2)
#> graphics * 3.4.4 2018-03-15 local
#> grDevices * 3.4.4 2018-03-15 local
#> grid 3.4.4 2018-03-15 local
#> gtable 0.2.0 2016-02-26 CRAN (R 3.4.1)
#> haven 1.1.1 2018-01-18 CRAN (R 3.4.3)
#> hms 0.4.2 2018-03-10 CRAN (R 3.4.4)
#> htmltools 0.3.6 2017-04-28 CRAN (R 3.4.2)
#> httr 1.3.1 2017-08-20 CRAN (R 3.4.1)
#> jsonlite 1.5 2017-06-01 CRAN (R 3.4.1)
#> knitr 1.20 2018-02-20 CRAN (R 3.4.3)
#> lattice 0.20-35 2017-03-25 CRAN (R 3.4.4)
#> lazyeval 0.2.1 2017-10-29 CRAN (R 3.4.2)
#> lubridate 1.7.2 2018-02-06 CRAN (R 3.4.3)
#> magrittr 1.5 2014-11-22 CRAN (R 3.4.1)
#> memoise 1.1.0 2017-04-21 CRAN (R 3.4.2)
#> methods * 3.4.4 2018-03-15 local
#> mime 0.5 2016-07-07 CRAN (R 3.4.1)
#> mnormt 1.5-5 2016-10-15 CRAN (R 3.4.1)
#> modelr 0.1.1 2017-07-24 CRAN (R 3.4.1)
#> munsell 0.4.3 2016-02-13 CRAN (R 3.4.1)
#> nlme 3.1-131.1 2018-02-16 CRAN (R 3.4.4)
#> parallel 3.4.4 2018-03-15 local
#> pillar 1.2.1 2018-02-27 CRAN (R 3.4.3)
#> pkgconfig 2.0.1 2017-03-21 CRAN (R 3.4.1)
#> plyr 1.8.4 2016-06-08 CRAN (R 3.4.1)
#> psych 1.7.8 2017-09-09 CRAN (R 3.4.1)
#> purrr * 0.2.4 2017-10-18 CRAN (R 3.4.2)
#> R6 2.2.2 2017-06-17 CRAN (R 3.4.1)
#> Rcpp 0.12.16 2018-03-13 CRAN (R 3.4.4)
#> readr * 1.1.1 2017-05-16 CRAN (R 3.4.1)
#> readxl 1.0.0 2017-04-18 CRAN (R 3.4.1)
#> reshape2 1.4.3 2017-12-11 CRAN (R 3.4.3)
#> rlang 0.2.0.9001 2018-03-26 Github (r-lib/rlang@49d7a34)
#> rmarkdown 1.9 2018-03-01 CRAN (R 3.4.3)
#> rprojroot 1.3-2 2018-01-03 CRAN (R 3.4.3)
#> rvest 0.3.2 2016-06-17 CRAN (R 3.4.1)
#> scales 0.5.0.9000 2018-01-23 Github (hadley/scales@d767915)
#> sf * 0.6-1 2018-03-22 CRAN (R 3.4.4)
#> stats * 3.4.4 2018-03-15 local
#> stringi 1.1.7 2018-03-12 CRAN (R 3.4.4)
#> stringr * 1.3.0 2018-02-19 CRAN (R 3.4.3)
#> tibble * 1.4.2 2018-01-22 CRAN (R 3.4.3)
#> tidyr * 0.8.0 2018-01-29 CRAN (R 3.4.3)
#> tidyverse * 1.2.1 2017-11-14 CRAN (R 3.4.2)
#> tools 3.4.4 2018-03-15 local
#> udunits2 0.13 2016-11-17 CRAN (R 3.4.1)
#> units 0.5-1 2018-01-08 CRAN (R 3.4.3)
#> utils * 3.4.4 2018-03-15 local
#> withr 2.1.2 2018-03-26 Github (jimhester/withr@79d7b0d)
#> xml2 1.2.0 2018-01-24 CRAN (R 3.4.3)
#> yaml 2.1.18 2018-03-08 CRAN (R 3.4.3)
AFAICT,在您的示例中,您实际上是在每一行上编写一个循环(group/ungroup 围绕变异);通过在此循环中覆盖几何图形,您将获得最后一个特征的边界框,而不是整个几何图形列表列的边界框。问题是 st_difference 做所有成对差异,而不是行差异。您可以使用以下代码(需要来自 github 的 sf)获得逐行差异:
sf_opt2 <- sf_pts %>%
mutate(
ring1 = st_buffer(geometry, 50000),
ring2 = st_buffer(geometry, 100000)
) %>%
mutate(geometry = ring2 / ring1) %>%
select(val)
plot(sf_opt2)