在 R 中将 sf 包中的函数应用于每一行
Apply function from sf package to each row while in R
我正在使用 R 中的 sf 包,为此我正在尝试使用其中一个函数来创建线条。目标是将它们的函数应用到下面示例数据框中的每一行(列 4:3 和 6:5)。
df <- read.table(text = " from to from_lat from_lon to_lat to_lon travel_time
1 8015345 8849023 50.77083 6.105277 50.71896 6.041269 7.000000
2 8200100 8200101 49.60000 6.133333 49.63390 6.136765 8.000000
3 8200100 8200110 49.60000 6.133333 49.74889 6.106111 16.000000
4 8200100 8200510 49.60000 6.133333 49.61111 6.050000 4.857143
5 8200100 8200940 49.60000 6.133333 49.55129 5.845025 28.236842
6 8200100 8866001 49.60000 6.133333 49.68053 5.809972 37.000000
7 8200100 8869054 49.60000 6.133333 49.64396 5.904150 14.000000
8 8200101 8200100 49.63390 6.136765 49.60000 6.133333 7.000000
9 8200101 8200110 49.63390 6.136765 49.74889 6.106111 11.000000
10 8200110 8200100 49.74889 6.106111 49.60000 6.133333 17.074074", header = TRUE)
我知道如何为一行执行此操作:
library(sf)
library(dplyr)
x = matrix(as.numeric(c(df[1, c(4, 3)],
df[1, c(6, 5)])), ncol = 2, byrow = TRUE)
class(x)
typeof(x)
l1 = st_linestring(x = x)
lsf = l1 %>%
st_sfc() %>%
st_sf(crs = 4326)
plot(lsf) #just to confirm that it is a line
但我真正需要的是对每一行都这样做。我尝试使用 for 循环,但由于某种原因它弄乱了 sf
包 类。所以我假设解决方案将涉及 apply()
但我不确定如何。
如果我们需要对每一行都这样做,那么我们可以使用pmap
library(purrr)
library(dplyr)
df%>%
select(4, 6, 3, 5) %>%
pmap(~ c(...) %>%
matrix(., ncol = 2) %>%
st_linestring %>%
st_sfc %>%
st_sf(crc = 4326))
您可以使用 dplyr::rowwise()
进行行分组。
df %>% rowwise() %>%
mutate(line_sf = list(matrix(c(from_lon, to_lon, from_lat, to_lat), ncol = 2) %>%
st_linestring()) ) %>%
with(st_sfc(line_sf, crs = 4326)) %>%
plot()
我重新安排了最后一行(在 plot
之前),将 10 条线的观察结果折叠成一个单一的几何图形集,以便在此处绘制,但您可以将它们单独放置。
不需要dplyr的解决方案:
lsf <- mapply(function(a, b, c, d) {
list(matrix(c(a, b, c, d), ncol = 2) %>%
st_linestring())
}, df$from_lon, df$to_lon, df$from_lat, df$to_lat) %>%
st_sfc(crs = 4326)
plot(lsf)
我正在使用 R 中的 sf 包,为此我正在尝试使用其中一个函数来创建线条。目标是将它们的函数应用到下面示例数据框中的每一行(列 4:3 和 6:5)。
df <- read.table(text = " from to from_lat from_lon to_lat to_lon travel_time
1 8015345 8849023 50.77083 6.105277 50.71896 6.041269 7.000000
2 8200100 8200101 49.60000 6.133333 49.63390 6.136765 8.000000
3 8200100 8200110 49.60000 6.133333 49.74889 6.106111 16.000000
4 8200100 8200510 49.60000 6.133333 49.61111 6.050000 4.857143
5 8200100 8200940 49.60000 6.133333 49.55129 5.845025 28.236842
6 8200100 8866001 49.60000 6.133333 49.68053 5.809972 37.000000
7 8200100 8869054 49.60000 6.133333 49.64396 5.904150 14.000000
8 8200101 8200100 49.63390 6.136765 49.60000 6.133333 7.000000
9 8200101 8200110 49.63390 6.136765 49.74889 6.106111 11.000000
10 8200110 8200100 49.74889 6.106111 49.60000 6.133333 17.074074", header = TRUE)
我知道如何为一行执行此操作:
library(sf)
library(dplyr)
x = matrix(as.numeric(c(df[1, c(4, 3)],
df[1, c(6, 5)])), ncol = 2, byrow = TRUE)
class(x)
typeof(x)
l1 = st_linestring(x = x)
lsf = l1 %>%
st_sfc() %>%
st_sf(crs = 4326)
plot(lsf) #just to confirm that it is a line
但我真正需要的是对每一行都这样做。我尝试使用 for 循环,但由于某种原因它弄乱了 sf
包 类。所以我假设解决方案将涉及 apply()
但我不确定如何。
如果我们需要对每一行都这样做,那么我们可以使用pmap
library(purrr)
library(dplyr)
df%>%
select(4, 6, 3, 5) %>%
pmap(~ c(...) %>%
matrix(., ncol = 2) %>%
st_linestring %>%
st_sfc %>%
st_sf(crc = 4326))
您可以使用 dplyr::rowwise()
进行行分组。
df %>% rowwise() %>%
mutate(line_sf = list(matrix(c(from_lon, to_lon, from_lat, to_lat), ncol = 2) %>%
st_linestring()) ) %>%
with(st_sfc(line_sf, crs = 4326)) %>%
plot()
我重新安排了最后一行(在 plot
之前),将 10 条线的观察结果折叠成一个单一的几何图形集,以便在此处绘制,但您可以将它们单独放置。
不需要dplyr的解决方案:
lsf <- mapply(function(a, b, c, d) {
list(matrix(c(a, b, c, d), ncol = 2) %>%
st_linestring())
}, df$from_lon, df$to_lon, df$from_lat, df$to_lat) %>%
st_sfc(crs = 4326)
plot(lsf)