Почему as.data.frame выдает ошибку при преобразовании растра с факторами в качестве данных и указании xy = T?

Я хотел бы преобразовать растровый слой в фрейм данных и получить координаты.

Это работает нормально, но не дает значений xy:

as.data.frame(raster_layer) 

as.data.frame (x = naip_svm_cropped)

               category
1   forest_broadleafdark
2   forest_broadleafdark
3   forest_broadleafdark
4              grassland
5              grassland
6              grassland

Это вызывает ошибку:

as.data.frame(raster_layer, xy = T)

Ошибка:

Ошибка при сопоставлении (round (v), rat $ ID): ошибка при оценке аргумента 'x' при выборе метода для функции 'match': Ошибка в v [, i]: неправильное количество измерений

Я подозреваю, что проблема где-то в таблице атрибутов растра, но не знаю, что делать дальше. Полагаю, я мог бы преобразовать коэффициенты в числовые и попробовать перейти оттуда (xy=T работает для нефакторных растров), но я хотел бы выяснить, почему добавление xy=T дает эту ошибку. Итак, мой вопрос действительно таков: «Почему это происходит и как я могу заставить это работать (возвращать значения xy со значениями ячеек)?»

В растровом слое есть факторы как данные (я не знаю, как его назвать, вот инструкция str):

str(naip_svm_cropped@data)
Formal class '.SingleLayerData' [package "raster"] with 13 slots
  ..@ values    : logi(0) 
  ..@ offset    : num 0
  ..@ gain      : num 1
  ..@ inmemory  : logi FALSE
  ..@ fromdisk  : logi TRUE
  ..@ isfactor  : logi TRUE
  ..@ attributes:List of 1
  .. ..$ :'data.frame': 5 obs. of  2 variables:
  .. .. ..$ ID      : num [1:5] 0 1 2 3 4
  .. .. ..$ category: Factor w/ 5 levels "forest_broadleafdark",..: 4 1 2 3 5
  ..@ haveminmax: logi TRUE
  ..@ min       : num 0
  ..@ max       : num 4
  ..@ band      : int 1
  ..@ unit      : chr ""
  ..@ names     : chr "madison_classcombine"

Поведение фрейма данных с такой структурой:

str(mad_veg_cropped@data)
Formal class '.SingleLayerData' [package "raster"] with 13 slots
 ..@ values    : logi(0) 
 ..@ offset    : num 0
  ..@ gain      : num 1
  ..@ inmemory  : logi FALSE
  ..@ fromdisk  : logi TRUE
  ..@ isfactor  : logi FALSE
  ..@ attributes: list()
  ..@ haveminmax: logi TRUE
  ..@ min       : num -0.719
  ..@ max       : num 1.04
  ..@ band      : int 1
  ..@ unit      : chr ""
  ..@ names     : chr "PercentVeg"

head(as.data.frame(mad_veg_cropped, xy = T))
       x       y   PercentVeg
1 291855.5 4775116  0.7182595
2 291856.5 4775116  0.7402779
3 291857.5 4775116  0.7601378
4 291858.5 4775116  0.7702084
5 291859.5 4775116  0.7774438
6 291860.5 4775116  0.7574666

Я бы хотел получить столбец «категория», «x» и «y».

sessionInfo () R версия 3.1.2 (2014-10-31) Платформа: x86_64-apple-darwin13.4.0 (64-разрядная) другие прикрепленные пакеты: [1] raster_2.3-24 sp_1.0-17

dput(naip_svm_cropped)
    new("RasterLayer"
        , file = new(".RasterFile"
        , name = "/private/var/folders/yj/vjkj1yyx1n510rf_rggqdb640000gr/T/R_raster_tedward/2015-06-04_122215_4840_06850.grd"
        , datanotation = "INT2S"
        , byteorder = structure("little", .Names = "value")
        , nodatavalue = -32768
        , NAchanged = FALSE
        , nbands = 1L
        , bandorder = structure("BIL", .Names = "value")
        , offset = 0L
        , toptobottom = TRUE
        , blockrows = 0L
        , blockcols = 0L
        , driver = "raster"
        , open = FALSE
    )
        , data = new(".SingleLayerData"
        , values = logical(0)
        , offset = 0
        , gain = 1
        , inmemory = FALSE
        , fromdisk = TRUE
        , isfactor = TRUE
        , attributes = list(structure(list(ID = c(0, 1, 2, 3, 4), category = structure(c(4L, 
    1L, 2L, 3L, 5L), .Label = c("forest_broadleafdark", "grassland", 
    "shadow1_tree", "Unclassified", "urban_buildings"), class = "factor")), .Names = c("ID", 
    "category"), row.names = c(NA, -5L), class = "data.frame"))
        , haveminmax = TRUE
        , min = 0
        , max = 4
        , band = 1L
        , unit = ""
        , names = "madison_classcombine"
    )
        , legend = new(".RasterLegend"
        , type = character(0)
        , values = logical(0)
        , color = logical(0)
        , names = logical(0)
        , colortable = c("#000000", "#008B00", "#FF0000", "#FFFF00", "#FF00FF")
    )
        , title = character(0)
        , extent = new("Extent"
        , xmin = 291855
        , xmax = 311023
        , ymin = 4768423
        , ymax = 4775116
    )
        , rotated = FALSE
        , rotation = new(".Rotation"
        , geotrans = numeric(0)
        , transfun = function () 
    NULL
    )
        , ncols = 19168L
        , nrows = 6693L
        , crs = new("CRS"
        , projargs = "+proj=utm +zone=16 +datum=NAD83 +units=m +no_defs"
    )
        , history = list()
        , z = list()
    )

person Tedward    schedule 04.06.2015    source источник
comment
Вы запрашиваете преобразование дискретного класса в числовой класс. Кажется разумным выдать ошибку. Почему бы не опубликовать dput(naip_svm_cropped), если вы хотите протестировать обходной путь.   -  person IRTFM    schedule 04.06.2015
comment
Хм, я не знаю, ясно ли я говорю, или я не понимаю, что вы имеете в виду. Я постараюсь уточнить вопрос, но я не пытаюсь менять коэффициенты на числовые. Я пытаюсь получить значения xy в дополнение к уровню фактора, назначенному каждому пикселю.   -  person Tedward    schedule 04.06.2015
comment
Я думаю, что понял. Я предложил вам опубликовать dput() из объекта, чтобы у нас действительно были некоторые данные для работы.   -  person IRTFM    schedule 04.06.2015
comment
ах, попался. Я никогда раньше этого не делал, но опубликую. Сообщите мне, как изменить, если необходимо (это займет много времени)   -  person Tedward    schedule 04.06.2015
comment
Спасибо. Я пытался восстановить растр из этого вывода, но получаю ошибку, которая не имеет для меня смысла. Если бы у меня была куча свободного времени (больше), я бы поискал в архивах SIG-geo ,.   -  person IRTFM    schedule 04.06.2015
comment
Хорошо, спасибо за ваши усилия, я постараюсь найти решение.   -  person Tedward    schedule 04.06.2015
comment
dput часто не очень полезен для растровых объектов, поскольку они часто зависят от данных в файле, к которым у вас не будет доступа.   -  person Robert Hijmans    schedule 05.06.2015


Ответы (1)


'растр' ожидает, что первый столбец таблицы атрибутов растра будет целочисленной переменной с именем 'ID'. Как у вас появился этот слой? Возможно, это ошибка, которую нужно исправить, или, возможно, вы допустили ошибку при ее создании.

В любом случае, вот обходной путь, который должен сработать:

xy <- xyFromCell(raster_layer, 1:ncell(raster_layer))
v <- as.data.frame(raster_layer) 
xyv <- data.frame(xy, v)

Вот самодостаточный пример

library(raster)
r <- raster(nrow=10, ncol=10)
r[] = 1
r[51:100] = 2
r[3:6, 1:5] = 3
r <- ratify(r)

rat <- levels(r)[[1]]
rat$landcover <- c('Pine', 'Oak', 'Meadow')
rat$code <- c(12,25,30)
levels(r) <- rat

xy <- xyFromCell(r, 1:ncell(r))
v <- as.data.frame(r) 
xyv <- data.frame(xy, v)

head(xyv)
#     x  y landcover code
#1 -162 81      Pine   12
#2 -126 81      Pine   12
#3  -90 81      Pine   12

хотя в этом примере вы также можете:

vv <- as.data.frame(r, xy=TRUE) 
person Robert Hijmans    schedule 05.06.2015
comment
Спасибо за ваше решение, оно решает мою проблему. Похоже, ошибка была очень специфичной для моего растрового объекта (что может быть связано с тем, как он был создан, читается в tiff) - person Tedward; 05.06.2015