Tengo un número de rásteres de tamaño variable que necesitan ser muestreados aleatoriamente con el valor de retorno siendo una matriz de x, y, y valor. El paquete raster sampleRandom(raster,n, na.rm=TRUE, xy=TRUE)
lo hará bien la mayoría de las veces. Cuando funciona correctamente, esta función devuelve una matriz de valores no-NA para n
pares de coordenadas. Cuando aparecen valores NA en la muestra, se descartan y se sustituyen por un valor no NA.
Sin embargo, para mis rásteres (el más pequeño tiene 4e^7 celdas y algunos tienen un alto porcentaje de valores NA), sampleRandom()
devuelve una matriz sustancialmente menor que n
pares de coordenadas. Presumiblemente, esto se debe a que los valores NA muestreados, no son reemplazados cuando se muestrean.
¿Por qué el sampleRandom
¿la función devuelve resultados incompletos en el ejemplo de datos del mundo real?
Como ha señalado correctamente @Radar, la documentación de los paquetes rasterizados indica: With argument na.rm=TRUE, the returned sample may be smaller than requested
Con esto, mi pregunta se convierte en; ¿cómo puedo dibujar un trabajo alrededor de esto y eficientemente dibujar muestra aleatoria de n
¿pares de coordenadas?
Ejemplo 1: esto funciona correctamente en la recuperación de una muestra aleatoria de n
a partir de un raster más grande recortado y enmascarado por polígonos espaciales. devuelve una matriz de 2000 puntos cordiantes.
region1 <- rbind(c(0,0), c(50,0), c(50,50), c(20,20), c(0,0))
region2 <- rbind(c(50,0), c(80,0), c(100,50), c(60,40), c(80,20), c(50,0))
polys <- SpatialPolygons(list(Polygons(list(Polygon(region1)), "region1"),
Polygons(list(Polygon(region2)), "region2")))
r <- raster(ncol=1000, nrow=1000)
r[] <- runif(ncell(r),0,1)
extent(r) <- matrix(c(0, 0, 1000, 1000), nrow=2)
r_crop <- crop(r, extent(polys), snap="out", progress='text')
r_mask <- mask(r_crop, polys)
plot(r_mask)
plot(polys, add=TRUE)
x <- sampleRandom(r_mask,2000, na.rm=TRUE, xy=TRUE)
nrow(x)
>[1] 2000
Ejemplo 2: El siguiente ejemplo es con datos reales que consisten en un raster universal (geo.r) de 2e^8 celdas y un subconjunto de polígonos espaciales (geo.poly) que contiene 1200 polígonos y es de menor extensión que geo.r. Este código resulta incorrectamente en una matriz de mucho menos de n
Dependiendo de la muestra aleatoria, algunas ejecuciones producen una matriz de entre 3 y 117 pares de coordenadas que no son AN.
require(maptools)
Prj <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"
modeling_areas_SHP <- "C:/.../modeling_areas_dissolve.shp"
geo.polys <- readShapePoly(modeling_areas_SHP, IDvar="area_ID", proj4string=CRS(Prj))
geo.poly <- modeling_areas[modeling_areas$area_ID == i,] #subset the shapefile
geo.r <- raster("C:/.../cost_raster")
geo.r_crop <- crop(geo.r, extent(geo.poly), snap="out", progress='text')
geo.r_mask <- mask(geo.r_crop, geo.poly, progress='text')
plot(geo.r_mask)
plot(geo.poly, add=TRUE)
x <- sampleRandom(geo.r_mask,2000, na.rm=TRUE, xy=TRUE)
nrow(x)
>[1] 117
Al menos para mí, los ejemplos anteriores son iguales salvo por el tamaño total de los rásteres y la complejidad de los polígonos; dos factores muy importantes. Obviamente, no puedo proporcionar los datos del mundo real debido al tamaño de los archivos, pero espero que el código sea suficiente.
¿Cómo puedo solucionarlo?
Utilicé este truco de trabajo, pero no es súper eficiente. Sin embargo, fue más eficiente que usar spsample()
del paquete "sp".
micro_sample = 50000
tmp_rand_smple <- data.frame(x = numeric(0), y = numeric(0), layer = numeric(0))
while(nrow(tmp_rand_smple) < micro_sample){
tmp_smple <- data.frame(sampleRandom(geo.r_mask,10000, na.rm=TRUE, xy=TRUE)) ### 10k is an arbitrary chunk, loops until > micro_sample
tmp_rand_smple <- rbind(tmp_rand_smple, tmp_smple)
tmp_rand_smple <- unique(tmp_rand_smple[c("x", "y", "layer")]) # remove any duplicate coordinate pairs
}
tmp_rand_smple <- tmp_rand_smple[1:micro_sample,] # trim to length of micro_sample
Ejemplo 3: Este es un ejemplo del código anterior que puede reproducirse con el shapefile vinculado. En mi ordenador, este código no devuelve el número requerido de muestras aleatorias https://www.dropbox.com/s/7poaqcxju808arw/riverine_region_1.zip
Prj <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"
geo.poly <- readShapePoly("FILE LOCATION:/riverine_region_1", IDvar="area_ID", proj4string=CRS(Prj)) ## set file location
r <- raster(ncol=5202, nrow=8182)
r[] <- runif(ncell(r),0,1)
extent(r) <- matrix(c( 1533500, 592219.7, 1447689, 537662.6), nrow=2)
r_crop <- crop(r, extent(geo.poly), snap="out", progress='text')
r_mask <- mask(r_crop, geo.poly, progress='text')
plot(r_mask)
plot(geo.poly, add=TRUE)
x <- sampleRandom(r_mask,2000, na.rm=TRUE, xy=TRUE)
nrow(x)
1 votos
¿No veo su pregunta? ¿Así que quieres reducir la complejidad de los subconjuntos muestreados aleatoriamente?
0 votos
Mi pregunta es: ¿Por qué el ejemplo de código del mundo real devuelve una matriz de sólo 3 pares de coordenadas, cuando se supone que debe devolver una muestra aleatoria de 2000. En el ejemplo 1, funciona correctamente, pero no funciona correctamente en el ejemplo 2.
0 votos
Utilizando datos simulados en los que una trama de 10.000 por 10.000 contiene sólo 10.000 celdas sin ADN, no pude reproducir este problema:
sampleRandom(..., 2000, na.rm=TRUE, xy=TRUE)
produce una matriz de 2000 por 3 sin valores NA en ella. (R
versión 2.15.2.)0 votos
Gracias por su observación whuber. Tienes razón; los datos simulados arriba son para demostrar cómo se supone que funciona. Debido al tamaño del archivo, no puedo proporcionar el conjunto de datos para los que no funciona. Sin embargo, proporciono el código para mostrar que es el mismo método que el ejemplo de datos simulados que funciona. La imagen de abajo muestra la complejidad de la máscara del shapefile. Todo dentro de la máscara tiene un valor raster. Los valores NA provienen de la región más allá de los bordes de la máscara shapefile, pero dentro de la extensión raster.
0 votos
Parece que
sampleRandom()
tiene una tramancell()
límite de tamaño, o un límite de relación de valor NA a no NA, después del cualna.rm=TRUE
sólo devuelve la lista de celdas con valor y no profundiza para reemplazar los valores NA que muestreó. Por lo tanto, devuelve una matriz de 117 por 3 sin valores NA cuandosampleRandom(geo.r_mask,2000, na.rm=TRUE, xy=TRUE)
geo.r_mask es un5202, 8182, 42562764 (nrow, ncol, ncell)
raster con sólo 637506 celdas con valores no NA.0 votos
Utilicé una trama casi 2,5 veces mayor que la tuya pero no pude reproducir el problema, así que no parece que el límite de tamaño de las celdas sea el culpable. Sería útil si pudieras publicar un código que la gente pudiera utilizar para reproducir el error en lugar de depender de un conjunto de datos privado.
0 votos
Whuber, agradezco su disposición a ayudar con este problema. He editado mi post original para incluir un tercer ejemplo que cuando se ejecuta en mi máquina recrea los resultados erróneos.