[R-sig-Geo] Better print method for Spatial*DataFrames?

Edzer Pebesma edzer.pebesma at uni-muenster.de
Sun May 30 01:34:40 CEST 2010


On 05/29/2010 11:47 AM, Roger Bivand wrote:

> On Sat, 29 May 2010, Barry Rowlingson wrote:
> 
>> On Sat, May 29, 2010 at 10:06 AM, Roger Bivand <Roger.Bivand at nhh.no>
>> wrote:
>>
>>
>>> In other software systems (octave, Stata, ...), one can turn on and
>>> off a
>>> more/less screen-by-screen displayer (not scrolling upwards, just
>>> chunking),
>>> but I'm not aware of an equivalent in R/S. I'm not sure how head() and
>>> tail() work in R,
>>
>> They don't seem to work very well at all for Spatial*DataFrames. If I
>> add coordinates to meuse to get a SpatialPointsDataFrame and
>> head(that) I get all the 'rows' but with only the cadmium
>> measurements. It's slicing it the wrong way. Odd.
>>
>>> and personally use str() by default. If I need to access
>>> the coordinates of a particular line or polygon, I print() just that
>>> list
>>> element (Line or Polygon object).
>>>
>>> I can see what you mean, but feel that users will benefit much more
>>> by using
>>> str(), which is a real gem!
>>
>> str is great if you need to know the str-ucture of an R object. But
>> it doesn't even align the values so you can see across rows of your
>> data, which is what I'd like print to do (by analogy with
>> print.data.frame).
>>
>> Currently if I print a SpatialPolygonsDataFrame I get the structure.
>> Print methods should do better than that - you're almost suggesting
>> not having, for example, a print method for data frames and that we'd
>> be better off having what print.default(anyDataFrame) gives us.
>>
>> So my proposal is that print of a SpatialPolygonsDataFrame class
>> should print like a data frame but with some indicator of the geometry
>> at the start of the row, such as POLYGON(...) - literally with dots,
>> there's no need to spell it out. Similarly for Lines.
>>
>> Another suggestion is for head() and tail methods on
>> Spatial*DataFrame objects - I think just subscripting [1:n,] from the
>> object and returning would do it. I think currently head and tail
>> treat these objects as lists and the results are not pretty.
> 
> Right, because they see S4 objects as lists with no components, only
> with attributes. str() does have support for S4 objects. They would need
> to be wrapped around an S4 show/print method, with the output captured,
> as in capture.output(). Would it make sense to have the default
> print/show for Spatial* be str() with max.level= set, and for
> Spatial*DataFrame be the print method for the data slot prepended with
> some text (perhaps POINT, MULTILINESTRING, MULTIPOLYGON, PIXEL, CELL, or
> better an abbreviation)?

In the following example:

require(maptools)
nc = readShapePoly(system.file("shapes/sids.shp", package =
"maptools")[1], IDvar="FIPSNO", proj4string=CRS("+proj=longlat
+ellps=clrk66"))
str(as(nc, "SpatialPolygons"))
as(nc, "SpatialPolygons")

I personally find the output of the (current) print method producing
much easier readable than that of str. Partly because I've grown
accustomed to it, but also partly because I have never liked the output
of str. I tend to use the current default show method used for
SpatialLines* and SpatialPolygons* (the generic show for S4 objects) to
figure out what the structure of the data is, not how to use it. So I
guess for those who want to use the data without bothering about the
deeper structure, these print methods (both: current show.S4 and str)
are not so useful. If you disagree with this: please respond!

As for Barry's proposal, I find it a bit repetitive (and space
consuming) to have a POINT(1 1) instead of the current (1,1) (which,
credits where credits go, is from a package Barry wrote that preceded
sp). I can very well understand that many people will not know how to
read WKT [1], as it again is something that programmers tend to find
useful, not users; to be right we need the awfully long words
MULTILINESTRING and MULTIPOLYGON to represent the sp classes, and then
can't write the whole string but need to abbreviate. I agree with Barry
that a representation as much as possible like a data.frame is most useful.

I suggest the folloging: for points:

  geometry attr1 attr2 attr3
PT(234 45)   333   xxy  22.5
PT(455 68)   221   xxx  13.2

for polygons: use PN(3;2335) to express that this MULTIPOLYGON consists
of 3 POLYGONS, and has 2335 coordinates (in total)

  geometry attr1 attr2 attr3
PN(3;2335)   333   xxy  22.5
PN(45;345)   221   xxx  13.2

for lines:

  geometry attr1 attr2 attr3
LI(3;2335)   333   xxy  22.5
LI (5;345)   221   xxx  13.2

for pixels: use points, replace PT with PX

for grids: don't print all the values, but a very short summary.

To really educate users that we "glue" data.frame attribute tables to
geometries, they need to see this, and therefore I want to print a
SpatialPoints object as:

  geometry
PT(234 45)
PT(455 68)

and do the same for SpatialLines and SpatialPolygons:

  geometry
PN(3;2335)
PN(45;345)

  geometry
LI(3;2335)
LI (5;345)

what head and tail should do is then obvious.

Next thing is that developers/programmers need to find out how to print
all the gory details -- they will need to use str(nc) or show(unclass(nc)).

For those from Europe: thank you for all the points in the song contest.
We also like Lena a lot, here at home.

[1] http://en.wikipedia.org/wiki/Well-known_text
-- 
Edzer Pebesma
Institute for Geoinformatics (ifgi), University of Münster
Weseler Straße 253, 48151 Münster, Germany. Phone: +49 251
8333081, Fax: +49 251 8339763  http://ifgi.uni-muenster.de
http://www.52north.org/geostatistics      e.pebesma at wwu.de



More information about the R-sig-Geo mailing list