Существует ли переменная, которая содержит текущую строку для фильтрации подмножества в R? - PullRequest
0 голосов
/ 02 января 2019

Я хочу отфильтровать большой фрейм данных, который содержит широту и долготу. Я хочу использовать метод distHaversine(), который генерирует расстояние между двумя точками по широте и долготе. При этом я хочу отфильтровать измерения, которые находятся далеко от города. Метод ожидает 2 вектора, одну опорную точку и одну конкретную точку, каждый из которых содержит 2 значения (широта, долгота).

Есть ли универсальная переменная, которую я могу выбрать, чтобы взять lat, lon из моего фрейма данных, например distHaversine(c(8.682127, 50.110922), c([i,lat], [i,lon]))?

Мой обходной путь - просто фильтровать по конкретным значениям широты и долготы. Спасибо за помощь:)

Использование значений lat и lon приведет к ошибке, так как метод вычислит расстояние для одной точки, а не для всего набора. Поэтому мне нужно всегда принимать одно значение за раз для этой функции.

Ошибка оценки: неправильная длина для вектора должна быть 2.

library(geosphere)   
library(readr)


ff <- function(x, pos)  subset(x, distHaversine(c(8.682127, 50.110922), c(lat, lon))<60000,    select= c(lat, lon, timestamp, value ))


yy <- readr::read_csv2_chunked("data.csv", DataFrameCallback$new(ff), 
    chunk_size = 100000, col_names = TRUE)

edit: по некоторым причинам, lat и long являются целыми числами, без двойных значений. Я отметил это и разделил на 1000 для расчетов

    dput(head(yy, 20))
structure(list(lat = c(52023, 42139, 43762, 52023, 54644, 52023, 
52023, 51278, -32879, 52023, 51434, 52023, 42139, 43762, 52023, 
52023, 52023, -32879, 52023, 52023), lon = c(4692, 24794, -79185, 
4692, 9760, 4692, 4692, 12588, -68877, 4692, 6115, 4692, 24794, 
-79185, 4692, 4692, 4692, -68877, 4692, 4692), timestamp =    structure(c(1538352021, 
1538352035, 1538352044, 1538352050, 1538352061, 1538352080, 1538352110, 
1538352110, 1538352132, 1538352140, 1538352147, 1538352170, 1538352183, 
1538352192, 1538352200, 1538352230, 1538352260, 1538352283, 1538352290, 
1538352320), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    P1 = c("1.2", "10.80", "3.00", "1.7", "12.3", "2.0", "1.0", 
    "4.75", "1.00", "1.0", "19.3", "1.8", "11.60", "4.00", "1.0", 
    "0.8", "1.0", "2.00", "1.1", "1.3")), .Names = c("lat", "lon", 
"timestamp", "P1"), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")) 

Результатом должен быть отфильтрованный фрейм данных

lat     lon     timestamp    P1        
9,5     50,5     1.1.2019    123    
8,8     49,3     1.1.2019    23     
...

1 Ответ

0 голосов
/ 02 января 2019

Это подход с обратным ходом, который использует функцию pmap_df для запуска distHaversine для каждой пары координат широта / долгота и возврата фрейма данных с результатами.Затем вы можете отфильтровать выходные данные по точкам, которые находятся на некотором расстоянии друг от друга.

library(geosphere)   
library(tidyverse)

# Fake data
set.seed(2)
dat = data.frame(lon=runif(5,-180,180), lat = runif(5,-90,90))

dist = pmap_df(data.frame(t(combn(1:nrow(dat), 2))), 
               ~data.frame(dat[.x, ] %>% set_names(c("lon1","lat1")), 
                           dat[.y, ] %>% set_names(c("lon2", "lat2")), 
                           dist=distHaversine(dat[.x, ], dat[.y, ])))

dist
         lon1       lat1       lon2       lat2     dist
1  -113.44239  79.825493   72.85465 -66.751384 18570291
2  -113.44239  79.825493   26.39748  60.020787  4259930
3  -113.44239  79.825493 -119.50131  -5.756667  9533243
4  -113.44239  79.825493  159.78216   8.997074  8969682
5    72.85465 -66.751384   26.39748  60.020787 14616198
6    72.85465 -66.751384 -119.50131  -5.756667 11905205
7    72.85465 -66.751384  159.78216   8.997074 10803902
8    26.39748  60.020787 -119.50131  -5.756667 13347748
9    26.39748  60.020787  159.78216   8.997074 11326140
10 -119.50131  -5.756667  159.78216   8.997074  9104543

Если вы просто хотите быстрый способ получить расстояния между заданным широтом / широтойlon координаты (чтобы конкретизировать, скажем, координаты во второй строке фрейма данных) и все остальные координаты, вот подход с использованием базовой функции R apply:

apply(dat[-2, ], 1, function(ll) distHaversine(dat[2,], ll))
       1        3        4        5 
18570291 14616198 11905205 10803902
...