Применить функцию из пакета sf к каждой строке, находясь в R - PullRequest
0 голосов
/ 29 апреля 2018

Я работаю с пакетом sf в R, и для этого я пытаюсь использовать одну из их функций для создания строк. Цель состоит в том, чтобы применить их функции к каждой строке (столбцы 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(), но я не знаю, как это сделать.

Ответы [ 3 ]

0 голосов
/ 29 апреля 2018

Вы можете использовать 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 линий в один набор геометрии для построения графика, но вы можете просто оставить их как отдельные элементы.

enter image description here

0 голосов
/ 29 апреля 2018

Решение, не требующее 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)

enter image description here

0 голосов
/ 29 апреля 2018

Если нам нужно сделать это в каждой строке, то мы можем использовать pmap

library(purrr)
library(dplyr)
df%>%
  select(4, 6, 3, 5) %>% 
  pmap(~ c(...) %>% 
            matrix(., ncol = 2) %>% 
            st_linestring %>%
            st_sfc %>%
            st_sf(crc = 4326))
...