Bezdepbonusu7Программирование: статьи и ответы

Вопрос

R Обрезать растр без данных

Автор вопроса: WrafОтветов: 5

Я хотел бы обрезать часть некоторых растров без данных (пример изображения в 1 где нет данных выделено черным) без определения экстента вручную.

Есть идеи?

изображение без данных

  • Пожалуйста, проверьте мой пост ниже, чтобы в следующий раз предоставить воспроизводимый пример, чтобы проиллюстрировать вашу проблему. Спасибо. Simon O'Hanlon 30.10.2013
  • Всегда есть риск, что внутри вашего изображения могут быть какие-то значения данных. Что ты хочешь делать тогда? Carl Witthoft 30.10.2013
  • @Carl: в моем случае внутри нет никаких данных. Я хочу обрезать изображение только на основе верхнего левого и нижнего правого угла, где доступны данные. Wraf 30.10.2013
  • @Wraf, так поможет ли вам нижеприведенное? Если нет, то почему? Опишите нерешенную проблему, и я обновлю свое решение. Ваше здоровье. Simon O'Hanlon 31.10.2013

rcroprasterrastervisterra

Ответы

Ответ 1 · рейтинг 20 · Robert Hijmans

Вы можете использовать trim для удаления внешних строк и столбцов, которые имеют только значения NA:

library(raster)
r <- raster(ncols=18,nrows=18)
r[39:49] <- 1
r[205] <- 6
s <- trim(r)

Чтобы изменить другие значения на NA или наоборот, вы можете использовать reclassify. Например, чтобы изменить NA на 0:

x <- reclassify(r, cbind(NA, 0))

Ответ 2 · рейтинг 4 · Simon O'Hanlon

[ методы подмножества и [<- замены определены для raster объектов, поэтому вы можете просто выполнить r[ r[] == 1 ] <- NA, чтобы избавиться от значений, где 1 - ваше значение nodata (используйте NAvalue(r), чтобы узнать, что R считает вашим значением nodata, если вы этого не сделаете). Конечно).

Обратите внимание, что вы должны использовать r[] внутри команды поднастройки [ для доступа к значениям. Вот рабочий пример...

Пример

#  Make a raster from system file
logo1 <- raster(system.file("external/rlogo.grd", package="raster"))

#  Copy to see difference
logo2 <- logo1

#  Set all values in logo2 that are > 230 to be NA
logo2[ logo2[] > 230 ] <- NA

#  Observe difference
par( mfrow = c( 1,2 ) )
plot(logo1)
plot(logo2)

Ответ 3 · рейтинг 4 · Marie Auger-Methe

У меня есть 2 немного разных решения. Первый требует ручной идентификации экстента, но использует предопределенные функции. Второй более автоматический, но немного более ручной.

Создайте воспроизводимый растр, для которого первые 2 строки NA

library(raster)
# Create a reproducible example
r1 <- raster(ncol=10, nrow=10)
# The first 2 rows are filled with NAs (no value)
r1[] <- c(rep(NA,20),21:100)

Решение №1

Вручную получить экстент из нанесенного рисунка с помощью drawExtent()

plot(r1)
r1CropExtent <- drawExtent()

Обрезать растр, используя экстент, выбранный на рисунке.

r2 <- crop(r1, r1CropExtent)

График для сравнения

layout(matrix(1:2, nrow=1))
plot(r1)
plot(r2)

Решение №2

Он идентифицирует строки и столбцы растра, которые имеют только значения NA, и удаляет те, которые находятся на краю растра. Затем он вычисляет экстент, используя extent().

Преобразуйте растр в матрицу, которая определяет, являются ли значения NA или нет.

r1NaM <- is.na(as.matrix(r1))

Найдите столбцы и строки, которые не полностью заполнены NA

colNotNA <- which(colSums(r1NaM) != nrow(r1))
rowNotNA <- which(rowSums(r1NaM) != ncol(r1))

Найдите экстент нового растра, используя первый и последний столбцы и строки, которые не полностью заполнены NA. Используйте crop(), чтобы обрезать новый растр.

r3Extent <- extent(r1, rowNotNA[1], rowNotNA[length(rowNotNA)],
   colNotNA[1], colNotNA[length(colNotNA)])
r3 <- crop(r1, r3Extent)

Постройте растры для сравнения.

layout(matrix(1:2, nrow=1))
plot(r1)
plot(r3)

Ответ 4 · рейтинг 1 · Boris Leroy

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

Поэтому я написал функцию защиты памяти, которая будет использовать метод Мари, если на компьютере достаточно ОЗУ (поскольку это самый быстрый способ), или метод, основанный на растровых функциях, если на компьютере недостаточно ОЗУ (он медленнее, но безопаснее для памяти). ).

Вот функция:

plotCroppedRaster <- function(x, na.value = NA)
{
  if(!is.na(na.value))
  {
    x[x == na.value] <- NA
  }
  if(canProcessInMemory(x, n = 2))
  {
    x.matrix <- is.na(as.matrix(x))
    colNotNA <- which(colSums(x.matrix) != nrow(x))
    rowNotNA <- which(rowSums(x.matrix) != ncol(x))

    croppedExtent <- extent(x,
                            r1 = rowNotNA[1],
                            r2 = rowNotNA[length(rowNotNA)],
                            c1 = colNotNA[1],
                            c2 = colNotNA[length(colNotNA)])

    plot(crop(x, croppedExtent))
  } else
  {
    xNA <- is.na(x)
    colNotNA <- which(colSums(xNA) != nrow(x))
    rowNotNA <- which(rowSums(xNA) != ncol(x))

    croppedExtent <- extent(x,
                            r1 = rowNotNA[1],
                            r2 = rowNotNA[length(rowNotNA)],
                            c1 = colNotNA[1],
                            c2 = colNotNA[length(colNotNA)])

    plot(crop(x, croppedExtent))
  }
}

Примеры :

library(raster)
r1 <- raster(ncol=10, nrow=10)
r1[] <- c(rep(NA,20),21:100)

# Uncropped
plot(r1)
# Cropped
plotCroppedRaster(r1)

# If the no-data value is different, for example 0
r2 <- raster(ncol=10, nrow=10)
r2[] <- c(rep(0,20),21:100)

# Uncropped
plot(r2)
# Cropped
plotCroppedRaster(r2, na.value = 0)

Ответ 5 · Tung

Если вы используете пакет rasterVis (любая версия после 25 июня 2021 г.), NA значения для terra SpatRaster

Установите rasterVis разрабатываемую версию с GitHub.

if (!require("librarian")) install.packages("librarian")
librarian::shelf(raster, terra, oscarperpinan/rastervis)
# Create a reproducible example
r1 <- raster(ncol = 10, nrow = 10)

# The first 2 rows are filled with NAs (no value)
r1[] <- c(rep(NA, 20), 21:100)

levelplot() для r1

rasterVis::levelplot(r1,
                     margin = list(axis = TRUE))

Преобразуйте в terra's SpatRaster, затем снова постройте, используя levelplot()

r2 <- rast(r1)
rasterVis::levelplot(r2,
                     margin = list(axis = TRUE))

Создана 26 июня 2021 г. в пакете reprex (v2.0.0)

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы