Анализ пространственных данных между двумя точками в R с использованием очень большого набора данных - PullRequest
1 голос
/ 19 июня 2020

Это мой первый раз, когда я пишу код на R с нуля, и я не могу подойти к нему. Я смотрю на гнезда черепах и их близость к источникам света (т. Е. Дома, фонарные столбы и т. Д. c.), Чтобы определить, как часто источник света находится в пределах заданного радиуса гнезда.

Это оба очень больших набора данных (сотни тысяч строк), поэтому код, вероятно, должен будет запускать al oop для каждой позиции вложения. Координаты GPS для обоих наборов данных указаны в десятичных градусах.

Данные о гнезде - это широта, долгота, наблюдаемая дата и вид (если известны)

Данные источника света - это широта, долгота, type, и несколько других параметров, связанных со светом, которые я хотел бы сохранить в наборе данных. очень признателен! Для каждого источника света в пределах r для гнезда я бы хотел, чтобы конечный результат выдавал всю строку данных источника света (тип, местоположение, дополнительные параметры, связанные со светом и т. Д. c.), Если это возможно, скорее, чем просто сказать, сколько значений было T по сравнению с F для нахождения внутри r. Спасибо!

> Nest <- read.csv("Nest.csv", header=T)
> Lights <- read.csv("Lights.csv", header=T)
> #Nest
> dput(droplevels(Nest[1:10, ]))
structure(list(LAT = c(34.146535, 34.194585, 34.216854, 34.269901, 
34.358718, 34.37268, 34.380848, 34.394183, 34.410384, 34.415077
), LONG = c(-77.839787, -77.804013, -77.787032, -77.742722, -77.63655, 
-77.619872, -77.609373, -77.591654, -77.568456, -77.561256), 
    DATE = structure(c(2L, 3L, 4L, 5L, 6L, 8L, 9L, 10L, 1L, 7L
    ), .Label = c("2016-05-19T03:12", "2016-05-21T07:23", "2016-05-23T08:14", 
    "2016-05-24T04:21", "2016-05-25T11:15", "2016-05-27T05:12", 
    "2016-05-27T09:45", "2016-05-28T09:42", "2016-05-28T10:18", 
    "2016-05-29T02:26"), class = "factor"), SPECIES = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "Cc", class = "factor")), row.names = c(NA, 
10L), class = "data.frame")
> #Lights
> dput(droplevels(Lights[1:10, ]))
structure(list(LAT = c(34.410925, 34.410803, 34.410686, 34.410476, 
34.410361, 34.410237, 34.410151, 34.410016, 34.409821, 34.409671
), LONG = c(-77.568183, -77.568296, -77.568478, -77.568757, -77.568915, 
-77.569135, -77.569355, -77.569527, -77.569707, -77.569905), 
    DATE = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
    ), .Label = "5/19/2016", class = "factor"), TYPE = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "R", class = "factor"), 
    WATTS = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, 
10L), class = "data.frame")

1 Ответ

0 голосов
/ 19 июня 2020

Поскольку вы заявили, что ваши наборы данных были большими, предлагаемое решение пытается избежать полного декартова произведения между всеми Nest и всеми Lamps. Для этого мы используем возможности неравнозначного соединения data.table, которые допускают только простые операторы, такие как > или <. Это позволяет сделать первый фильтр ламп в коробке вокруг гнезда. Это поле должно быть достаточно большим, чтобы содержать кружок максимального расстояния до Nest. На втором этапе мы вычисляем расстояние по отфильтрованным данным (гораздо меньше вычислений, чем декартово произведение всех данных):

library(data.table)
library(geosphere)

#To data.table
setDT(Nest)
setDT(Lights)

# Define a box around each nest
dlon<- 0.001
dlat <- 0.001

Nest[,c("LATNest","LONGNest","latmin","latmax","longmin","longmax"):=.(LAT,LONG,LAT-dlat, LAT+dlat,LONG-dlon,LONG+dlon)]
Nest[,c("LAT","LONG") :=.(NULL,NULL)]

# Search lights in box
LightNearNest <- Nest[Lights, .(LATNest,LONGNest, LATLight = LAT, LONGLight = LONG), on = .(latmin<LAT , latmax>LAT,longmin<LONG,longmax>LONG),nomatch=0,allow.cartesian=T]     


# Calculate distance 
LightNearNest[,dist:= geosphere::distHaversine(cbind(LONGNest,LATNest),cbind(LONGLight,LATNest))]
LightNearNest

    LATNest  LONGNest LATLight LONGLight      dist
1: 34.41038 -77.56846 34.41092 -77.56818 25.072269
2: 34.41038 -77.56846 34.41080 -77.56830 14.694370
3: 34.41038 -77.56846 34.41069 -77.56848  2.020476
4: 34.41038 -77.56846 34.41048 -77.56876 27.643784
5: 34.41038 -77.56846 34.41036 -77.56892 42.154475
6: 34.41038 -77.56846 34.41024 -77.56914 62.359234
7: 34.41038 -77.56846 34.41015 -77.56936 82.563993
...