2013-07-31 5 views
2

Возможно ли как-то легко работать с данными в Spatial*DataFrame (* = Точки, линии, многоугольники, пиксели, сетка, ...)? В частности, у меня есть трудности с присвоением значений его и работать с ними:Присвоить и использовать значения данных Spatial * DataFrame легко

require(gstat) 
data(meuse) 
coordinates(meuse) = ~x+y 
data(meuse.grid) 
gridded(meuse.grid) = ~x+y 

######## 1) assigning value 

meuse[1,'zinc'] <- NA 
# Error in meuse[1, "zinc"] <- NA : object of type 'S4' is not subsettable 
as.data.frame(meuse)[1,'zinc'] <- NA 
# Error in as.data.frame(meuse)[1, "zinc"] <- NA : 
# could not find function "as.data.frame<-" 

######## 2) operating with values 

meuse[, 'zinc'] + 2 
# Error in meuse[, "zinc"] + 2 : non-numeric argument to binary operator 

я нашел довольно уродливые обходные пути для обоих случаев:

# ad 1) 
meuse2 <- as.data.frame(meuse) 
meuse2[1, 'zinc'] <- NA 
meuse2 <- SpatialPointsDataFrame(SpatialPoints(meuse), meuse2) 

# ad 2) 
as.data.frame(meuse)[, 'zinc'] + 2 

, но это только попытки начинающих, слишком уродливый и сложный ... Должно быть намного проще в R!

+1

meuse $ zinc [1] <- NA Похоже, что другие пути к этому не предоставляются как методы, но их можно добавить. Я посмотрю на это. Вы могли бы ожидать, что meuse [1, «цинк»] <- NA, meuse [1,] [['цинк]]] <- NA, а meuse [1,] $ zinc <- NA должны работать. Вероятно, лучше избегать оператора @, если сможете. – mdsumner

+1

Также это работает, поэтому вы можете избежать $: meuse [['цинк]] [1] <- NA – mdsumner

+0

@mdsumner, ничего себе, так много возможностей! Но что вы скажете о '@' -операторе, почему я должен его избегать? Это не только интересно, но и кажется важным; пожалуйста, напишите как ваш собственный ответ! – TMS

ответ

5

Для объектов Spatial * DataFrame вы можете получить доступ к слоту data.frame с помощью '@data', и обычные операции data.frame должны работать. Используя ваш пример,

[email protected][1, 'zinc'] <- NA 

дает

str([email protected]) 
'data.frame': 155 obs. of 12 variables: 
$ cadmium: num 11.7 8.6 6.5 2.6 2.8 3 3.2 2.8 2.4 1.6 ... 
$ copper : num 85 81 68 81 48 61 31 29 37 24 ... 
$ lead : num 299 277 199 116 117 137 132 150 133 80 ... 
$ zinc : num NA 1141 640 257 269 ... 
... 
+0

Вот что я пропустил так долго, спасибо! – TMS

5

Вы можете сделать это так:

meuse$zinc[1] <- NA 

или, лучше, так как вы можете использовать имя переменной, а не буквальным:

aname <- 'zinc' 
meuse[[aname]][1] <- NA 

Кажется, что другой путь s к этому не предоставляются как методы, но они могут быть добавлены. Я не уверен, почему это так, но первоначально часть *DataFrame была построена как AttributeList в sp, так как фактический data.frame R был неэффективен с именами ростов в то время, но это древняя история и все зафиксировано сейчас.

Вы могли бы ожидать, что они будут работать, как обычный data.frame, но они этого не делают:

meuse[1,'zinc'] <- NA 
meuse[1,][['zinc']] <- NA 
meuse[1,]$zinc <- NA 

Это, вероятно, лучше, чтобы избежать оператора @, если вы можете, потому что это для разработчиков, чтобы скрыть внутри кода они предоставляют пользователям, т. е. подрывают их API, если вы не используете предоставленные методы. В этом нет никакой серьезной опасности, за исключением того, что разработчики могут изменить API, и ваш код не будет работать, и вы можете повредить объект, изменив одну часть, но не другую в том, как был создан объект, поэтому вы не должны использовать это за исключением частных или в коде, который вы поддерживаете активно (я думаю, что это безопасно в этом случае, но избегайте его вообще, если можете). См. «@» И «Слот» для основ.

+0

Спасибо!1), так что вы думаете, что это ошибка, что эти 3 заявления не работают? Может кто-нибудь это исправить? 2) является ли функция '@ data'' Spatial * DataFrame' документирована где-то? Можно принять это как критерий, который разумно использовать. Похоже, что они также используют форму 'df [['zinc']] [1]' [intro_sp vignette] (http://cran.r-project.org/web/packages/sp/vignettes/intro_sp.pdf) , – TMS

+0

Что мне не нравится в этих более «правильных» способах, так это то, что я обычно не использую data.frames. Данные 'df @ [1, 'цинк']' близки к тому, что я использую обычно. И что еще более важно, с '@ data' ** вы можете работать с ним как с dataframe - индексирование нескольких столбцов по имени или индексу: **' meuse @ data [, c ('цинк', 'cadmium')] 'unfortunatelly would не работают в форме 'meuse [[]]'. – TMS

+0

Это работает теперь meuse [1, 'цинк'] <- NA, введенный в sp 1.0-12 – mdsumner

 Смежные вопросы

  • Нет связанных вопросов^_^