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

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

Есть идеи?

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


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


Ответы (5)


Вы можете использовать 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))
person Robert Hijmans    schedule 05.12.2015
comment
Я обнаружил, что trim работает очень медленно, но решение Мари Оже-Мете № 2, приведенное ниже, работает отлично и быстро. - person see24; 13.09.2018

[ методы подмножества и [<- замены определены для 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)

введите здесь описание изображения

person Simon O'Hanlon    schedule 30.10.2013
comment
Спасибо за помощь. В моем случае у меня всегда есть центральная непрерывная зона с данными, и никаких данных нет снаружи. Но действительно, ваш пример - person Wraf; 04.11.2013

У меня есть 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)
person Marie Auger-Methe    schedule 31.10.2013
comment
РЕШЕНИЕ № 2 хорошее, но есть ошибка, вы должны инвертировать ncol и nrow... Я сделал редактирование, и теперь это правильно - person WAF; 01.02.2014
comment
@WAF: вы правы, это была опечатка. Решение № 2 теперь должно быть правильным. - person Marie Auger-Methe; 02.02.2014

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

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

Вот функция:

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)
person Boris Leroy    schedule 02.12.2015
comment
Многое из того, что внутри функции, можно вынести из оператора if(canProcessInMemory(x, n = 2)) - person Tung; 25.06.2021

Если вы используете пакет 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)

person Tung    schedule 27.06.2021