R: Вставка средних значений пар строк данных - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть ряд координат из Стравы, которые записываются каждые 2,5 минуты, а затем добавляются к карте QGIS.Я хочу интерполировать точки между ними, взяв среднее значение широты и долготы каждой пары.

Я знаю, что мог бы использовать цикл for, но я бы предпочел использовать одну из функций семейства apply.Я знаю, что мне нужно взять текущую строку, а затем следующую строку для всех, кроме последней строки.

gpsSmall представляет собой data.frame выглядит следующим образом

activity_no lat     lon
----------- ---     ---
1           52.5111 -1.85222
1           52.5111 -1.86224
1           52.5111 -1.87226
... etc
2           52.6189 -1.85332
2           52.6284 -1.86332
2           52.6386 -1.87332
... etc

Я тогда написал этифункции для создания дополнительных строк, которые я добавлю в конец.

splitPoints <- function(point1, point2) {
    meanLatitude = (point1$lat + point2$lat)/2
    meanLongitude = (point1$lon + point2$lon)/2

    point1$lat = meanLatitude
    point1$lon = meanLongitude

    point1
}

newPoints <- sapply(seq_len(nrow(gpsSmall) - 1),
       function(i){
           splitPoints(gpsSmall[i,], gpsSmall[i+1,])
       })

Однако newPoints возвращает матрицу из 3 (количество столбцов в gpsSmall) x 66 (1 - количество строк в gpsSmall). Что я делаю не так?

1 Ответ

0 голосов
/ 11 февраля 2019

Не использовать функции применения, но что-то вроде этого может сделать это немного проще.Учитывая то, что я думаю, что ваша проблема, это должно сделать это.Я предположил, что вы хотели, чтобы activity_no был механизмом группировки.Если нет, это еще проще.Просто используйте функцию approx, как описано ниже для всего набора данных, вместо того, чтобы разбивать ее сначала.

Пара tidyverse пакетов:

library(dplyr)
library(purrr)

Загрузите фрагмент данных:

dat <- tribble(
  ~activity_no, ~lat, ~lon,
  1,           52.5111, -1.85222,
  1,           52.5111, -1.86224,
  1,           52.5111, -1.87226,
  2,           52.6189, -1.85332,
  2,           52.6284, -1.86332,
  2,           52.6386, -1.87332
)

А теперь просто выполните линейную интерполяцию, используя ?approx.Установка длины интерполяционного выхода равной n * 2 - 1 в основном говорит, что между каждым реальным наблюдением есть 1 новое значение.Так как это линейно, это будет среднее.Вы можете настроить вывод и получить больший уровень интерполяции, если хотите.

dat %>%
  split(dat$activity_no) %>%
  map_dfr( ~ data.frame(activity_no = rep(.$activity_no[1], nrow(.) * 2 - 1),
                lat = approx(.$lat, n = nrow(.) * 2 - 1)$y,
                lon = approx(.$lon, n = nrow(.) * 2 - 1)$y))

   activity_no      lat      lon
1            1 52.51110 -1.85222
2            1 52.51110 -1.85723
3            1 52.51110 -1.86224
4            1 52.51110 -1.86725
5            1 52.51110 -1.87226
6            2 52.61890 -1.85332
7            2 52.62365 -1.85832
8            2 52.62840 -1.86332
9            2 52.63350 -1.86832
10           2 52.63860 -1.87332
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...