Mais

Pontos de amostragem aleatória em R com restrição de distância mínima?

Pontos de amostragem aleatória em R com restrição de distância mínima?


Estou tentando selecionar aleatoriamente um número de pontos dentro do meu quadro de dados (dados de exemplo abaixo) com uma restrição de que a distância mínima entre o ponto selecionado deve ser maior do que uma certa distância. Eu consegui fazer a seleção aleatória usando oamostrafunção em R, mas não consigo descobrir como adicionar o bit de restrição em meu código. Suponho que isso envolva o uso de algum pacote de análise espacial em R, mas não tenho ideia por onde começar.

Eu sei que o ArcGIS tem uma ferramenta chamada Criar Pontos Aleatórios que pode especificar a distância mínima entre os pontos. Mas minha situação requer um número maior de amostragens repetidas, fazendo-me sentir que fazer isso em R seria muito mais fácil porque pode ser incorporado com um loop.

Dados de exemplo:

grid_index x y grid_168 323012.5 674187.5 grid_169 323012.5 674212.5 grid_292 323037.5 672287.5 grid_293 323037.5 672312.5 grid_368 323037.5 674187.5 grid_369 323037.5 674212.5

Você pode fazer isso com R ou ArcGIS independentemente.

Com ArcGIS, primeiro crie uma classe de recurso (por exemplo, arquivo de forma) a partir de suas coordenadas de grade. Em seguida, use esta classe de recurso de grade como parâmetro constraining_extent da ferramenta "Criar pontos aleatórios".

A única codificação que você precisa fazer é colocar essa ferramenta em um loop que pode ser obtido através do Model Builder ou Arcpy.

aqui está um exemplo (100 iteração):

import arcpy for i in range (100): print i arcpy.CreateRandomPoints_management ("c: / data / project", "samplepoints", "c: /data/studyarea.shp", "", 500, "", "POINT "," ")

Para R, use genrandompnts do site de ecologia espacial. Esta ferramenta é semelhante à ferramenta ArcGis "Criar Pontos Aleatórios".

Além disso, há outro tópico semelhante à sua pergunta.

Como criar pontos aleatórios fora dos polígonos?


Se bem entendi, você deseja desenhar uma amostra aleatória com restrição de distância de seus dados para cada observação nos dados. Isso é semelhante a uma análise de K vizinho mais próximo.

Aqui está um exemplo de fluxo de trabalho que criará uma amostra aleatória de kNN, usando uma restrição de distância mínima, e adicionará o nome de linha correspondente de volta aos seus dados.

Adicionar bibliotecas e dados de exemplo

dados da biblioteca (sp) (meuse) coordenadas (meuse) <- ~ x + y

Calcule uma matriz de distância usando spDists

dmat <- spDists (meuse)

Defina a distância mínima de amostra e defina como NA na matriz de distância. Aqui é onde você criaria qualquer tipo de restrição, digamos, uma faixa de distância.

min.dist <- 500 dmat [dmat <= min.dist] <- NA

Aqui, iteramos por cada linha na matriz de distância e selecionamos uma amostra aleatória! = NA. O objeto "samples" é um data.frame onde ID são os nomes de domínio do objeto de origem e kNN é o nome de domínio do vizinho mais próximo. Observação; há algum tratamento de NA adicionado apenas no caso de nenhum vizinho ser encontrado, o que poderia acontecer com restrições de distância.

samples <- data.frame (ID = rownames (meuse @ data), kNN = NA) para (i em 1: nrow (dmat)) {x <- as.vector (dmat [, i]) nomes (x) < - amostras $ ID x <- x [! is.na (x)] if (! comprimento (x) == 0) {amostras [i,] [2] <- nomes (x) [amostra (1: comprimento ( x), 1)]} else {samples [i,] [2] <- NA}}

Podemos então adicionar a coluna kNN, contendo os nomes de domínio do vizinho mais próximo, aos dados originais.

meuse @ data <- data.frame (meuse @ data, kNN = samples $ kNN) head (meuse @ data)

Também podemos subconjunto as observações únicas do vizinho mais próximo.

meuse.sub <- meuse [which (rownames (meuse @ data)% in% unique (samples $ kNN)),]

Existem maneiras muito mais elegantes de realizar essa análise, mas este fluxo de trabalho fornece uma ideia geral. Eu recomendaria dar uma olhada na biblioteca spdep e nas funções dnearneigh ou knearneigh para uma solução mais avançada.


Se alguém estiver interessado em pontos de amostragem com uma restrição de distância para cada polígono, entretanto, existem duas possibilidades interessantes e rápidas: (1) usando QGIS "pontos aleatórios dentro de polígonos" através do pacote RQGIS, ou (2) usando spatstat: : função rSSI.

Nos exemplos a seguir para (1) RQGIS e (2) spatstat :: rSSI:

## carregar pacotes relevantes if (! require ("pacman")) install.packages ("pacman") pacman :: p_load (sf, sp, rgdal, dplyr, mapview, spatstat, maptools, devtools) ## carregar dados e converter to sf columbus <- readOGR (system.file ("shapes / columbus.shp", package = "spData") [1])%>% sf :: st_as_sf (.) ## iniciar amostragem aleatória com restrição de distância # # # # # # # # # # # # # # # # # # # # # # # # # (1)… usando RQGIS # # # # # # # # # # # # # # # # # # # # # # # devtools :: install_github (" jannes-m / RQGIS ") library (" RQGIS ") #… abrir túnel QGIS RQGIS :: open_app () # QGIS deve ser instalado #… encontrar algoritmo adequado RQGIS :: find_algorithms (search_term =" random ") # [6]" Pontos aleatórios dentro dos polígonos (fixos) # ----------------> qgis: randompointsinsidepolygonsfixed "# [7]" Pontos aleatórios dentro dos polígonos (variável) # -------- -----> qgis: randompointsinsidepolygonsvariable "#… verificar o uso RQGIS :: get_usage (alg =" qgis: randompointsinsidepolygonsfixed ") RQGIS :: get_args_man (alg =" qgis: randompointsinsidepolygonsfixed ") #… processar ponto aleatório s com distância mínima (0,25 grau) # usando um número máximo fixo (10) rdnmPts.RQGIS <- RQGIS :: run_qgis (alg = "qgis: randompointsinsidepolygonsfixed", show_output_paths = TRUE, load_output = TRUE, params = list (VECTOR = columbus , MIN_DISTANCE = "0,25", VALUE = "10", OUTPUT = "rndm_pts.shp")) #… dê uma olhada no resultado mapview :: mapview (list (rdnmPts.RQGIS, columbus)) #… verifique o número de aleatórios points nrow (rdnmPts.RQGIS) # [1] 187 # # # # # # # # # # # # # # # # # # # # # (2)… using spatstat :: rSSI -------- ---------------------------- # # # # # # # # # # # # # # # # # # # # # # spatstat :: rSSI usa uma entrada de formato especial. Portanto, uma função é criada # para transformar o recurso simples no formato owin. # init function genRandomPtsDist <- function (x, seed = 123, dist = 10, n = Inf, maxit = 100, quiet = TRUE,…) {# get start time of process process.time.start <- proc.time ( ) # get crs crs <- sf :: st_crs (x = x) # converter recurso simples em polígonos espaciais x.sp <- x%>% as (., "Spatial")%>% as (., "SpatialPolygons" ) # converter em objeto owin x.owin <- x.sp%>% slot (., "polygons")%>% lapply (X =., FUN = function (x) {sp :: SpatialPolygons (list (x) )})%>% lapply (X =., FUN = spatstat :: as.owin) # gera amostragem aleatória com restrição distante (pode ser paralelizado) pts.ppp <- lapply (X = 1: length (x.owin) , FUN = função (i, x.owin, r, n, quiet, seed, maxit, ...) {if (quiet == FALSE) cat ("Run", i, "of", length (x.owin), " n") set.seed (seed) spatstat :: rSSI (r = r, n = n, giveup = maxit, win = x.owin [[i]],…)}, quiet = quiet, x.owin = x.owin, r = dist, n = n, seed = seed, maxit = maxit,…) # conversão reversa para recurso simples pts.sf <- pts.ppp%>% lapply (X =., FUN = função (x) sf :: st_as_sfc (as (x, "Sp atialPoints ")))%>% do.call (c,.)%>% sf :: st_sf (., crs = crs) # obtém itens interceptados pts.inter.x <- sf :: st_intersects (x = pts. sf, y = x)%>% unlist if (length (pts.inter.x)! = nrow (pts.sf)) {warning ("Alguns pontos de amostra estão fora de um polígono")} else {pts.sf $ In <- pts.inter.x} # obter tempo de processo process.time.run <- proc.time () - process.time.start if (quiet == FALSE) cat (paste0 ("------ Executar de genRandomPtsDist: ", round (x = process.time.run [" elapsed "] [[1]] / 60, dígitos = 3)," Minutos ------  n ")) return (pts.sf )} # fim da função ## Usando a função definida, agora pode-se gerar uma amostra aleatória. # ... processar pontos aleatórios com distância mínima (0,25 grau) # usando um número máximo fixo (10) rdnmPts.rSSI <- genRandomPtsDist (x = columbus, dist = 0,25, n = 10, quiet = FALSE) # ... dê uma olhada em o resultado mapview :: mapview (list (rdnmPts.rSSI, columbus)) #… verifique o número de pontos aleatórios nrow (rdnmPts.rSSI) # [1] 171

Assista o vídeo: Inventários Florestais - Introducao ao R