[R-sig-Geo] Subsetting SpatialPolygonsDataFrame and empty ID slots
Roger Bivand
Roger.Bivand at nhh.no
Tue Oct 30 12:24:55 CET 2007
On Tue, 30 Oct 2007, Agustin Lobo wrote:
> That's really helpful, thanks.
>
> For "everyday" use, I've made:
>
> "slotspol" <- function(pol, sl="ID")
> sapply(slot(pol, "polygons"), function(x) slot(x, sl))
>
> Which can be used for any slot name:
> slotspol(Up)
> slotspol(Up,"area")
>
> Also, few questions:
> 1. I observe that pols$Site is identical to pols at data$Site. Is not
> pols at data$Site the correct syntax? I mean that we retrieve variable "Site"
> from slot "data" in object "pols".
Both are possible, but "$" methods are provided for all Spatial*DataFrame
objects so that they behave like regular data frames in many settings, so
that coercing to data frame becomes unnecessary. Using the "@" directly is
not necessarily safe, so in particular please use the "$<-" method for
writing to (possibly new) variables in the Spatial*DataFrame. To see how
"$" works, try using a Spatial*DataFrame as the data= argument in lm() or
glm(), etc. It just "works".
>
> 2. In your code, I don't understand
> sites_Lupuna <- length(grep("Lupuna", as.character(pols$Site))) > 0
>
> because the result is just T (the result of length(grep("Lupuna",
> as.character(pols$Site))) is 3)
> and thus subsetting with sites_Lupuna yields an object that is identical
> to the original:
I don't have your data, so I cannot set up the condition vector exactly.
Here I was trying to be too clever, you want a vector of TRUE or FALSE
values of length 140, and this condition wasn't the right one.
cond <- "Aleman" %in% as.character(pols$Site)
should just have TRUE for Aleman, not otherwise. Your understanding below
is OK.
Roger
>
>> pols_Lupuna <- pols[sites_Lupuna,]
>> length(pols_Lupuna at polygons)
> [1] 140
>> length(pols at polygons)
> [1] 140
>
> Instead:
>> sites_Lupuna <- grep("Lupuna", as.character(pols$Site))
>> sites_Lupuna
> [1] 1 2 3
>> pols_Lupuna <- pols[sites_Lupuna,]
>
> seems to provide a correctly subset of the original pols object ("Lupuna 1",
> "Lupuna 2", "Lupuna 3")
>
> Am I wrong? I feel quite insecure on this.
>
> Agus
>
> Roger Bivand escribió:
>> On Mon, 29 Oct 2007, Agustin Lobo wrote:
>>
>> > Dear list,
>> >
>> > I have imported a shp file with:
>> >
>> > > pols <- readOGR("../AllTransectPolygons02",
>> > layer="AllTransectPolygons02")
>> >
>> > > class(pols)
>> > [1] "SpatialPolygonsDataFrame"
>> > attr(,"package")
>> > [1] "sp"
>> >
>> > > pols at data
>> > AREA PERIMETER Site
>> > 0 2500 1010 Lupuna 1
>> > 1 2500 1010 Lupuna 3
>> > 2 2500 1010 Lupuna 2
>> > 3 2500 1010 Aleman
>> > 4 2500 1010 Zancudoyacu
>> > etc
>> >
>> > and now I want to select few polygons according
>> > to a vector of Site names.
>> >
>> > Thinking on how doing this, I thought I could select
>> > the corresponding IDs in the data table and then use
>> > the ID slot in the polygons, but
>> > I've found that the polygons themselves actually
>> > lack the ID information:
>> >
>>
>> Please treat all the long named access thingies in sp as deprecated - they
>> will be flagged as such in the next release, and removed one release after
>> that. S4 is not like that.
>>
>> library(sp)
>> library(rgdal)
>> example(readOGR)
>> class(Up)
>> getSlots(class(Up))
>> class(slot(Up, "polygons")[[1]])
>> getSlots(class(slot(Up, "polygons")[1]))
>>
>> So:
>>
>> sapply(slot(Up, "polygons"), function(x) slot(x, "ID"))
>>
>> > > getPolygonsIDSlot(pols)
>> > Error in getPolygonsIDSlot(pols) :
>> > no slot of name "ID" for this object of class
>> > "SpatialPolygonsDataFrame"
>> >
>> > How does sp relate the data table to the polygons if there is no ID?
>> >
>>
>> Of course there is an ID, but you can get at either by:
>>
>> sapply(slot(pols, "polygons"), function(x) slot(x, "ID"))
>>
>> or
>>
>> rownames(as(pols, "data.frame"))
>>
>>
>> > In any case, which would the most efficient way of subseting
>> > the SpatialPolygonsDataFrame into another SpatialPolygonsDataFrame
>> > with the selected polygons?
>>
>> Returning to the original question, subsetting is simply by the "["
>> operator, just like any other data.frame:
>>
>> sites_Lupuna <- length(grep("Lupuna", as.character(pols$Site))) > 0
>> summary(sites_Lupuna)
>> pols_Lupuna <- pols[sites_Lupuna,]
>>
>> Just think of Spatial*DataFrame objects as data.frame objects and things
>> will be much clearer.
>>
>> Roger
>>
>> > Should I convert to a maptools object
>> > and use subset.polylist()? If so, how do I convert? I've tried:
>> >
>> > pols.maptools <- SpatialPolygons2PolySet(pols)
>> >
>>
>> PS. PolySet objects are really for drawing coastlines in this context.
>>
>> > but the data table is lost.
>> >
>> > Thanks!
>> >
>> >
>>
>
>
--
Roger Bivand
Economic Geography Section, Department of Economics, Norwegian School of
Economics and Business Administration, Helleveien 30, N-5045 Bergen,
Norway. voice: +47 55 95 93 55; fax +47 55 95 95 43
e-mail: Roger.Bivand at nhh.no
More information about the R-sig-Geo
mailing list