Найти ближайшие координаты между фреймами данных неравной длины - PullRequest
0 голосов
/ 11 июля 2019

У меня есть два фрейма данных неравного размера, которые называются OBS и REF.Оба содержат 9864 столбца - столбцы 1 и 2 - это долгота и широта, а столбцы 3-9864 - это дневные значения температуры за 27 лет.У них очень разное количество строк - у OBS есть 12375, а у REF всего 504.

OBS: 12375 obs. of 9864 variables

Lon     Lat     1979.01.01     1979.01.02     1979.01.03
0.000   39.75   13.69          13.14          13.32
1.000   39.75   12.93          12.41          12.59
2.000   39.75   11.78          10.62          11.15
3.000   39.75   11.73          10.94          12.16

REF: 504 obs. of 9864 variables

Lon      Lat       1979.01.01     1979.01.02     1979.01.03
0.0000   37.6559   12.69          12.35          12.60
2.8125   37.6559   13.43          12.97          13.23
5.6250   37.6559   13.91          13.64          13.71
8.4375   37.6559   14.12          14.24          14.01

Что я хочу сделать, это вывести новый фрейм данных (REF_Closest), который берет координаты из фрейма данных OBS,находит самые близкие координаты из фрейма данных REF и выводит эти координаты и все переменные справа от этого, например:

REF_Closest: 12375 obs. of 9864 variables

Lon      Lat       1979.01.01     1979.01.02     1979.01.03
0.0000   37.6559   12.69          12.35          12.60
0.0000   37.6559   12.69          12.35          12.60
2.8125   37.6559   13.43          12.97          13.23
2.8125   37.6559   13.43          12.97          13.23

Я пытался адаптировать другие подобные вопросы, но не могу решить это.Есть предложения?

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Я придумал решение data.table:

library(data.table)

# we will use this dummy variable to group by
ref[, id := 1:.N]

ref[, cbind(LonRef = Lon, 
      LatRef = Lat, 
      obs[which.min(as.matrix(dist(rbind(ref[.GRP, 1:2], 
                                         obs[, 1:2])))[2:(.N+1), 1]), ]), 
      by = id]

Что там:

  • cbind связывает столбцы трех разных источников:
    • Ссылочный лат
    • Ссылочный номер
    • и data.frame (тоже data.table) с наблюдаемыми показаниями.
  • Эти данные.фрейм рассчитывается следующим образом:
    • Рассчитать эккулидное расстояние с dist от текущей строки ref (отсюда .GRP) до всех пар лат-лон в obs (отсюда * 1025)*).
    • определяет минимум первого столбца, исключая самого себя (henche (2:.N))
    • Возвращает полный ряд obs для такого наблюдаемого минимального расстояния (это obs[...)

После чего я получил:

   id LonRef  LatRef Lon   Lat 1979.01.01 1979.01.02 1979.01.03
1:  1 0.0000 37.6559   0 39.75      13.69      13.14      13.32
2:  2 2.8125 37.6559   3 39.75      11.73      10.94      12.16
3:  3 5.6250 37.6559   3 39.75      11.73      10.94      12.16
4:  4 8.4375 37.6559   3 39.75      11.73      10.94      12.16

Я использовал данные:

obs <- fread("Lon     Lat     1979.01.01     1979.01.02     1979.01.03
 0.000   39.75   13.69          13.14          13.32
 1.000   39.75   12.93          12.41          12.59
 2.000   39.75   11.78          10.62          11.15
 3.000   39.75   11.73          10.94          12.16")

ref <- fread("Lon      Lat       1979.01.01     1979.01.02     1979.01.03
 0.0000   37.6559   12.69          12.35          12.60
 2.8125   37.6559   13.43          12.97          13.23
 5.6250   37.6559   13.91          13.64          13.71
+ 8.4375   37.6559   14.12          14.24          14.01")
0 голосов
/ 11 июля 2019

С небольшим изменением - добавление дополнительной строки = это даст вам номера строк в OBS, которые имеют самое близкое (евклидово) расстояние к каждой строке REF (то есть его избыточности).

> REF
     Lon     Lat X1979.01.01 X1979.01.02 X1979.01.03
1 0.0000 37.6559       12.69       12.35       12.60
2 2.8125 37.6559       13.43       12.97       13.23
3 5.6250 37.6559       13.91       13.64       13.71
4 8.4375 37.6559       14.12       14.24       14.01
> OBS
  Lon   Lat X1979.01.01 X1979.01.02 X1979.01.03
1   0 39.75       13.69       13.14       13.32
2   1 39.75       12.93       12.41       12.59
3   2 39.75       11.78       10.62       11.15
4   3 39.75       11.73       10.94       12.16
5   8 38.50       12.34       14.23       17.23


nearest.rows <- apply (OBS,1, function(OBSrow) 
                       which.min(sqrt((OBSrow[1] - REF$Lon)^2 + (OBSrow[2] - REF$Lat)^2))
                      )

> nearest.rows
[1] 1 1 2 2 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...