Вменение пропущенных данных об окружающей среде на основе геопространственного расстояния - PullRequest
1 голос
/ 25 октября 2019

Я хочу вменять пропущенные значения Temp на Станцию, заменяя среднее значение Temp на двух ближайших Станциях.

library(tidyverse)
library(lubridate)

tb1 <- 
  tibble::tibble(
    Date = as_date(rep(c("2019-01-01", "2019-01-02"), each = 4))
  , Stat = rep(c("F", "L", "M", "R"), times = 2)
  , Lat  = rep(c(31.418715, 31.582045, 30.181459, 33.626057), times = 2)
  , Long = rep(c(73.079109, 74.329376, 71.492157, 73.071442), times = 2)
  , Temp = c(NA, 20, 28, 25, 26, 25, NA, 24)
  )

tb1

# A tibble: 8 x 5
  Date       Stat    Lat  Long  Temp
  <date>     <chr> <dbl> <dbl> <dbl>
1 2019-01-01 F      31.4  73.1    NA
2 2019-01-01 L      31.6  74.3    20
3 2019-01-01 M      30.2  71.5    28
4 2019-01-01 R      33.6  73.1    25
5 2019-01-02 F      31.4  73.1    26
6 2019-01-02 L      31.6  74.3    25
7 2019-01-02 M      30.2  71.5    NA
8 2019-01-02 R      33.6  73.1    24

Это заменяет пропущенные значения средним значением непропущенной температуры на всех станциях.

impute.mean <- function(x) {
  replace(x, is.na(x), mean(x, na.rm = TRUE))
  }

tb1 %>% 
  group_by(Date) %>% 
  mutate(Temp1 = impute.mean(Temp))

# A tibble: 8 x 6
# Groups:   Date [2]
  Date       Stat    Lat  Long  Temp Temp1
  <date>     <chr> <dbl> <dbl> <dbl> <dbl>
1 2019-01-01 F      31.4  73.1    NA  24.3
2 2019-01-01 L      31.6  74.3    20  20  
3 2019-01-01 M      30.2  71.5    28  28  
4 2019-01-01 R      33.6  73.1    25  25  
5 2019-01-02 F      31.4  73.1    26  26  
6 2019-01-02 L      31.6  74.3    25  25  
7 2019-01-02 M      30.2  71.5    NA  25  
8 2019-01-02 R      33.6  73.1    24  24

Используется этот код для поиска расстояния между двумя станциями

library(geosphere)

distm(
    x = c(73.079109, 31.418715)
  , y = c(74.329376, 31.582045)
  , fun = distHaversine
  )

         [,1]
[1,] 120053.3

Не можете понять, как рассчитать расстояние с помощью tidyverse?

tb1 %>% 
  mutate(
    Dist = distm(
          x = c(Long, Lat)
        , y = c(Long, Lat)
        , fun = distHaversine
        )
    )

Ошибка в .pointsToMatrix (x): неверная длина для вектора, должна быть 2

1 Ответ

1 голос
/ 25 октября 2019

Я добавляю ниже решение с использованием пакета пространственного риска. Ключевые функции в этом пакете написаны на C ++ (Rcpp) и поэтому очень быстрые.

Станции в tb1 без наблюдения для Temp:

tb1_na <- tb1 %>% filter(is.na(Temp)) 

Создать функцию для определения расстояний достанции на определенную дату:

circle_fn <- function(x, y, z){
  spatialrisk::points_in_circle(tb1 %>% filter(Date == z), 
                                lon_center = x, 
                                lat_center = y, 
                                lon = Long, 
                                lat = Lat, 
                                radius = 1e6)
}

Поскольку каждый элемент выходных данных представляет собой фрейм данных, purrr :: map_dfr используется для связывания их вместе:

purrr::pmap_dfr(list(tb1_na$Long, tb1_na$Lat, tb1_na$Date), 
                circle_fn, .id = "tb1_na") %>%
   group_by(tb1_na) %>%
   slice(2:3) %>%
   summarize(Temp = mean(Temp)) %>%
   ungroup() %>%
   bind_cols(tb1_na, .) %>%
   select(-tb1_na)

Выход:

  Date       Stat    Lat  Long  Temp Temp1
  <date>     <chr> <dbl> <dbl> <dbl> <dbl>
1 2019-01-01 F      31.4  73.1    NA  24  
2 2019-01-02 M      30.2  71.5    NA  25.5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...