R 将函数按组应用于每一行和后续行

R 将函数按组应用于每一行和后续行,r,sf,R,Sf,我有一个sf数据框,其中包含标记许多单向街道交叉口位置的点。除“几何图形”列外,一列包含街道名称,另一列包含交叉点在单向街道上的相对位置 下面是一个玩具的例子。第一排是Arch St的第一个十字路口,第二排是Arch St的第二个十字路口,以此类推 library(sf) intersections <- structure(list(street = c("ARCH ST", "ARCH ST", "ARCH ST", "SANSOM ST", "SANSOM ST", "SANSO

我有一个sf数据框,其中包含标记许多单向街道交叉口位置的点。除“几何图形”列外,一列包含街道名称,另一列包含交叉点在单向街道上的相对位置

下面是一个玩具的例子。第一排是Arch St的第一个十字路口,第二排是Arch St的第二个十字路口,以此类推

library(sf)

intersections <- structure(list(street = c("ARCH ST", "ARCH ST", "ARCH ST", "SANSOM ST", 
"SANSOM ST", "SANSOM ST"), number = c(1L, 2L, 3L, 1L, 2L, 3L), 
    geometry = structure(list(structure(c(2699665.2606043, 236074.947200272
    ), class = c("XY", "POINT", "sfg")), structure(c(2699402.74765515, 
    236109.729280198), class = c("XY", "POINT", "sfg")), structure(c(2699202.95996668, 
    236136.613760229), class = c("XY", "POINT", "sfg")), structure(c(2699431.38476158, 
    234437.663731016), class = c("XY", "POINT", "sfg")), structure(c(2699162.09261096, 
    234476.514355583), class = c("XY", "POINT", "sfg")), structure(c(2697100.77148795, 
    234809.605567052), class = c("XY", "POINT", "sfg"))), precision = 0, bbox = structure(c(xmin = 2697100.77148795, 
    ymin = 234437.663731016, xmax = 2699665.2606043, ymax = 236136.613760229
    ), class = "bbox"), crs = structure(list(epsg = 2272L, proj4string = "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs"), class = "crs"), n_empty = 0L, class = c("sfc_POINT", 
    "sfc"))), row.names = c(NA, -6L), class = c("sf", "tbl_df", 
"tbl", "data.frame"), sf_column = "geometry", agr = structure(c(street = NA_integer_, 
number = NA_integer_), class = "factor", .Label = c("constant", 
"aggregate", "identity")))

> intersections
Simple feature collection with 6 features and 2 fields
geometry type:  POINT
dimension:      XY
bbox:           xmin: 2697101 ymin: 234437.7 xmax: 2699665 ymax: 236136.6
epsg (SRID):    2272
proj4string:    +proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs

# A tibble: 6 x 3
  street    number                 geometry
  <chr>      <int> <POINT [US_survey_foot]>
1 ARCH ST        1       (2699665 236074.9)
2 ARCH ST        2       (2699403 236109.7)
3 ARCH ST        3       (2699203 236136.6)
4 SANSOM ST      1       (2699431 234437.7)
5 SANSOM ST      2       (2699162 234476.5)
6 SANSOM ST      3       (2697101 234809.6)
如何按组(即街道)循环sf数据帧中的行,告诉每一行对该组中的下一行执行操作以填充新列,如果不存在这样的下一行,则返回NA?

最后,由于
mp_matrix()
调用了Google Maps API,这需要花钱,因此请使用
sf
中的
st_distance()
函数来生成以下内容

     street number travel_distance                 geometry
1   ARCH ST      1             576 POINT (2699665 236074.9)
2   ARCH ST      2             397 POINT (2699403 236109.7)
3   ARCH ST      3              NA POINT (2699203 236136.6)
4 SANSOM ST      1             410 POINT (2699431 234437.7)
5 SANSOM ST      2             440 POINT (2699162 234476.5)
6 SANSOM ST      3              NA POINT (2697101 234809.6)

非常感谢您的帮助。

我在玩弄您的示例,但我无法使用
st_distance
功能获得相同的
行驶距离

st_distance(intersections$geometry[1], intersections$geometry[2])

Units: [US_survey_foot]
         [,1]
[1,] 264.8072
通过行本身的循环或矢量化操作可以使用这段代码完成

# used librarys
library(units)
library(tidyverse)
library(sf)

# find distance function
find_Distance <- function(x) {

  # create lead list
  x_lead <- x[2:length(x)]

  # create distance matrix
  distance_matrix <- st_distance(x, x_lead)

  # diagonal of the distance matrix is your desired output, fill last entry with NA and 
  # unit
  c(diag(distance_matrix), set_units(NA, "US_survey_foot"))

}

# group by street and calculate distance
intersections <- group_by(intersections, street) %>%
  mutate(travel_distance = find_Distance(geometry))

# if needed, set unit of travel distance
units(intersections$travel_distance) <- as_units("US_survey_foot")

#二手图书馆
图书馆(单位)
图书馆(tidyverse)
图书馆(sf)
#求距离函数

找到距离谢谢。我应该澄清一下,我的
旅行距离
值只是个傻瓜。一个挑战是生成一个密集矩阵,并将对角线与我的实际用例相结合,
mp_matrix()
,这将是非常昂贵的。与
st_distance()
不同,
mp_matrix()
没有
by_element
(成对)参数,因此密集矩阵输出是唯一的选项。我通过添加您的
lead
列解决了这个问题,将
crossions
转换为一个列表,其中每个元素都是df行,并且
lappy()
ing
mp_matrix()
。结果矩阵是1x1,我将这些值合并回原始df。
# used librarys
library(units)
library(tidyverse)
library(sf)

# find distance function
find_Distance <- function(x) {

  # create lead list
  x_lead <- x[2:length(x)]

  # create distance matrix
  distance_matrix <- st_distance(x, x_lead)

  # diagonal of the distance matrix is your desired output, fill last entry with NA and 
  # unit
  c(diag(distance_matrix), set_units(NA, "US_survey_foot"))

}

# group by street and calculate distance
intersections <- group_by(intersections, street) %>%
  mutate(travel_distance = find_Distance(geometry))

# if needed, set unit of travel distance
units(intersections$travel_distance) <- as_units("US_survey_foot")