从分组数据中的点子集创建 sf multiploygon

Create sf multiploygon from a subset of points in grouped data

请注意,这个问题是 also posted here,但我会是一个更好的场所......?如果 SO 是一个好的场所,我可以删除 GIS 发布。

我有一个可重现的数据集,其中包含两只动物的重新定位(数据如下)。每个地点都有一个 DateTime 邮票和一个一般季节 IndYearCorePeriodWinterSummerNone)。

> head(dat)
       IndYear Latitude Longitude            DateTime IndYearCorePeriod
1 BHS_001-2015 45.01785 -111.5670 2015-01-07 05:52:00            Winter
2 BHS_001-2015 45.01799 -111.5674 2015-01-07 06:48:00            Winter
3 BHS_001-2015 45.01795 -111.5673 2015-01-07 07:15:00            Winter
4 BHS_001-2015 45.01733 -111.5408 2015-01-07 17:02:00            Winter
5 BHS_001-2015 45.01452 -111.5329 2015-01-08 19:01:00            Winter
6 BHS_001-2015 44.98944 -111.5415 2015-03-21 07:02:00              None

对于每个 IndYear 我想在 IndYearCorePeriod != "None" 时制作两个单独的多边形(即一个用于 Summer,另一个用于 Winter)。多边形可以表示最小凸多边形(即 mcpchull)。使用下面的 dat 我可以制作一个 sf 点对象,但无法制作如上所述的多边形。我的想法是在循环中工作,但怀疑 sfdplyr.

中有更好的方法

这些数据的理想解决方案是一个 sf 多多边形,每个多边形内的每个 IndYear. Once the polygons are created, my hope is to intersect the polygons with a larger point data set and summarize theDateTime` 值具有 SummerWinter 多边形。

我的真实数据代表了来自 350 IndYears 的近 100 万个位置。

datSF <- dat %>% 
  st_as_sf(coords = c("Longitude", "Latitude"), agr = "identity") %>%
    st_set_crs( "+proj=longlat +datum=WGS84")

关于从 datSF 生成多个多边形的想法将不胜感激。

dat <- structure(list(IndYear = c("BHS_001-2015", "BHS_001-2015", "BHS_001-2015", 
"BHS_001-2015", "BHS_001-2015", "BHS_001-2015", "BHS_001-2015", 
"BHS_001-2015", "BHS_001-2015", "BHS_001-2015", "BHS_001-2015", 
"BHS_001-2015", "BHS_001-2015", "BHS_001-2015", "BHS_001-2015", 
"BHS_011-2012", "BHS_011-2012", "BHS_011-2012", "BHS_011-2012", 
"BHS_011-2012", "BHS_011-2012", "BHS_011-2012", "BHS_011-2012", 
"BHS_011-2012", "BHS_011-2012", "BHS_011-2012", "BHS_011-2012", 
"BHS_011-2012", "BHS_011-2012", "BHS_011-2012"), Latitude = c(45.0178464, 
45.0179942, 45.0179475, 45.0173283, 45.0145206, 44.9894375, 44.9900889, 
44.9874772, 44.9897919, 44.9890256, 44.9420158, 44.9397328, 44.9412822, 
44.8635131, 44.8289894, 45.120814, 45.120802, 45.120761, 45.116529, 
45.105876, 45.104906, 45.103481, 45.119494, 45.118741, 45.118455, 
45.011676, 45.014516, 45.010205, 45.007998, 45.008031), Longitude = c(-111.5669881, 
-111.5673925, -111.5672922, -111.5408156, -111.5328619, -111.5414744, 
-111.5409731, -111.5406083, -111.5476233, -111.5411953, -111.4645483, 
-111.4678228, -111.464585, -111.4622411, -111.4641572, -110.817359, 
-110.817405, -110.818067, -110.806221, -110.797895, -110.793635, 
-110.791884, -110.800843, -110.80594, -110.803976, -110.837199, 
-110.841477, -110.84738, -110.838413, -110.839451), DateTime = structure(c(1420635120, 
1420638480, 1420640100, 1420675320, 1420768860, 1426942920, 1427036520, 
1427083320, 1427410920, 1427457660, 1435741200, 1435788000, 1435834860, 
1435975200, 1436022000, 1329436800, 1329458400, 1329480000, 1329501600, 
1329523200, 1334660400, 1334682000, 1334703600, 1334725200, 1334746800, 
1341054000, 1341075600, 1341097200, 1341118800, 1341140400), class = c("POSIXct", 
"POSIXt"), tzone = ""), IndYearCorePeriod = c("Winter", "Winter", 
"Winter", "Winter", "Winter", "None", "None", "None", "None", 
"None", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter", 
"Winter", "Winter", "Winter", "Winter", "None", "None", "None", 
"None", "None", "Summer", "Summer", "Summer", "Summer", "Summer"
)), class = "data.frame", row.names = c(NA, -30L))

'trick'就是用group_by,然后summarise。这会将所有点放在您定义的组中。然后,您可以使用 st_cast 创建您想要的任何内容,或者像本例一样,使用 st_convex_hull.

library( sf )

datSF <- dat %>% 
  st_as_sf(coords = c("Longitude", "Latitude") ) %>%
  st_set_crs( "+proj=longlat +datum=WGS84" ) %>%
  filter ( IndYearCorePeriod %in% c( "Summer", "Winter") ) %>%
  group_by( IndYear, IndYearCorePeriod ) %>%
  summarise() %>%
  st_convex_hull()

library(mapview)
mapview( datSF )