Недопустимое предупреждение `.internal.selfref`, столбец не обновляется при работе с `SpatialPolygonsDataFrame`

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

Для организации я хотел бы добавить эти атрибуты в свои SpatialPolygonsDataFrame через слияние и обновление, но я продолжаю получать предупреждение «Неверный .internal.selfref», и столбцы не будут добавлены.

Покопавшись в вопросах и ответах здесь, кажется быть связаны с тем фактом, что данные для объекта SpatialPolygonsDataFrame хранятся в list, но ответы не помогли, как с этим справиться, поскольку они обычно имели дело с определяемыми пользователем list, а не с теми, которые выходят из пакета, такого как здесь.

Вот простой пример использования глупого шейп-файла, скажем, U.S. Штаты (вы заметите, что ниже я использую разрешение 500k):

library(maptools)

us.states<-readShapePoly("cb_2014_us_state_5m.shp")

setDT(us.states@data) #works fine
> class(us.states@data)
[1] "data.table" "data.frame"

us.states@data[,test:=1L]

Предупреждающее сообщение: In`[.data.table`(us.states@data, , `:=`(test, 1L)) : Неверный .internal.selfref обнаружен и исправлен путем создания (поверхностной) копии data.table, чтобы := мог добавить этот новый столбец по ссылке. Ранее этот data.table был скопирован R (или создан вручную с помощью structure() или аналогичного). Избегайте key<-, names<- и attr<-, которые в настоящее время в R (как ни странно) могут копировать все data.table. Вместо этого используйте синтаксис set*, чтобы избежать копирования: ?set, ?setnames и ?setattr. Кроме того, в R<=v3.0.2 list(DT1,DT2) скопировал все DT1 и DT2 (list() R использовался для копирования именованных объектов); пожалуйста, обновитесь до R>v3.0.2, если это кусается. Если это сообщение не помогает, сообщите об этом в datatable-help, чтобы можно было устранить основную причину.

Такого рода jives с тем, что я собрал из других связанных ответов, но я, по крайней мере, ожидал, что данные будут обновлены, но, увы:

> names(us.states@data)
[1] "STATEFP"  "STATENS"  "AFFGEOID" "GEOID"    "STUSPS"   "NAME"  
    "LSAD"     "ALAND"    "AWATER"  

Можно ли продолжать использовать удобный синтаксис обновления := по ссылке для работы с SpatialPolygonsDataFrame (или аналогичным .shp извлеченным объектом)?

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

us.states@data<-copy(us.states@data)[,test:=1L]

> names(us.states@data)
 [1] "STATEFP"  "STATENS"  "AFFGEOID" "GEOID"    "STUSPS"   "NAME"     "LSAD"    
 [8] "ALAND"    "AWATER"   "test"   

person MichaelChirico    schedule 03.09.2015    source источник
comment
Как насчет us.states@data <- setDT(us.states@data)? Не идеально, но чтобы избежать копирования до тех пор, пока не будет исправлено.. Пожалуйста, сообщите об ошибке.. Я не помню реализации для объектов S4.   -  person Arun    schedule 03.09.2015
comment
@Arun сделано, спасибо. Однако я не думаю, что улавливаю ваш дрейф с предложенным вами исправлением. Возможно, вы имели в виду us.states@data<-setDT(us.states@data[,test:=1L]), который работает (но tracemem меняется)   -  person MichaelChirico    schedule 03.09.2015
comment
Никаких дрейфов. Я старался избегать использования copy(). setDT() выполняет свою работу, но неглубоко скопированный результат не назначается обратно родительской среде правильно. Отсюда явное использование <-. tracemem() не сильно поможет в R v3.1+, так как вы не можете сказать, поверхностное это копирование или глубокое. Попробуйте следующее: DF = data.frame(x=1:5, y=6:10); tracemem(DF); DF$z = 11:15.. It's all shallow copy, but still tracemem` сообщает. Мое предложение состояло в том, чтобы вы избегали глубокого копирования (пока что).   -  person Arun    schedule 03.09.2015
comment
@Arun кое-что еще, что я заметил в связи с этим - keep.rownames, похоже, не работает (например, setDT(us.states,keep.rownames=T) не работает). это очень важно, потому что порядок сюжета нарушается, когда я сливаю... Я полагаю, что это та же основная проблема. Должен ли я добавить его в FR?   -  person MichaelChirico    schedule 04.09.2015
comment
Как я уже упоминал, setDT() должен делать все, о чем вы просите. Он просто не может назначить его обратно родительской среде. Использование debugonce(setDT) и просмотр его построчно должно быть полезным.   -  person Arun    schedule 05.09.2015