[Rd] [.raster bug {was "str() on raster objects fails .."}
Simon Urbanek
simon.urbanek at r-project.org
Wed Feb 2 23:30:10 CET 2011
On Feb 1, 2011, at 8:16 PM, Paul Murrell wrote:
> Hi
>
> On 2/02/2011 2:03 p.m., Henrik Bengtsson wrote:
>> On Tue, Feb 1, 2011 at 4:46 PM, Paul Murrell<p.murrell at auckland.ac.nz> wrote:
>>> Hi
>>>
>>> On 1/02/2011 9:22 p.m., Martin Maechler wrote:
>>>>>>>>>
>>>>>>>>> Henrik Bengtsson<hb at biostat.ucsf.edu>
>>>>>>>>> on Mon, 31 Jan 2011 11:16:59 -0800 writes:
>>>>
>>>> > Hi, str() on raster objects fails for certain dimensions. For
>>>> > example:
>>>>
>>>> >> str(as.raster(0, nrow=1, ncol=100)) 'raster' chr [1, 1:100]
>>>> > "#000000" "#000000" "#000000" "#000000" ...
>>>>
>>>> >> str(as.raster(0, nrow=1, ncol=101)) Error in `[.raster`(object,
>>>> > seq_len(max.len)) : subscript out of bounds
>>>>
>>>> > This seems to do with how str() and "[.raster"() is coded; when
>>>> > subsetting as a vector, which str() relies on, "[.raster"()
>>>> > still returns a matrix-like object, e.g.
>>>>
>>>> >> img<- as.raster(1:25, max=25, nrow=5, ncol=5);
>>>> >> img[1:2]
>>>> > [,1] [,2] [,3] [,4] [,5]
>>>> > [1,] "#0A0A0A" "#3D3D3D" "#707070" "#A3A3A3" "#D6D6D6"
>>>> > [2,] "#141414" "#474747" "#7A7A7A" "#ADADAD" "#E0E0E0"
>>>>
>>>> > compare with:
>>>>
>>>> >> as.matrix(img)[1:2]
>>>> > [1] "#0A0A0A" "#3D3D3D"
>>>>
>>>>
>>>> > The easy but incomplete fix is to do:
>>>>
>>>> > str.raster<- function(object, ...) {
>>>> > str(as.matrix(object), ...);
>>>> > }
>>>>
>>>> > Other suggestions?
>>>>
>>>> The informal "raster" class is behaving ``illogical''
>>>> in the following sense:
>>>>
>>>> > r<- as.raster(0, nrow=1, ncol=11)
>>>> > r[seq_along(r)]
>>>> Error in `[.raster`(r, seq_along(r)) : subscript out of bounds
>>>>
>>>> or, here equivalently,
>>>> > r[1:length(r)]
>>>> Error in `[.raster`(r, 1:length(r)) : subscript out of bounds
>>>>
>>>> When classes do behave in such a way, they definitely need their
>>>> own str() method.
>>>>
>>>> However, the bug really is in "[.raster":
>>>> Currently, r[i] is equivalent to r[i,] which is not at all
>>>> matrix-like and its help clearly says that subsetting should
>>>> work as for matrices.
>>>> A recent thread on R-help/R-devel has mentioned the fact that
>>>> "[" methods for matrix-like methods need to use both nargs() and
>>>> missing() and that "[.dataframe" has been the example to follow
>>>> "forever", IIRC already in S and S-plus as of 20 years ago.
>>>
>>> The main motivation for non-standard behaviour here is to make sure that a
>>> subset of a raster object NEVER produces a vector (because the conversion
>>> back to a raster object then produces a single-column raster and that may be
>>> a "surprise"). Thanks for making the code more standard and robust.
>>>
>>> The r[i] case is still tricky. The following behaviour is quite convenient
>>> ...
>>>
>>> r[r == "black"]<- "white"
>>>
>>> ... but the next behaviour is quite jarring (at least in terms of the raster
>>> image that results from it) ...
>>>
>>> r2<- r[1:(nrow(r) + 1)]
>>>
>>> So I think there is some justification for further non-standardness to try
>>> to ensure that the subset of a raster image always produces a sensible
>>> image. A simple solution would be just to outlaw r[i] for raster objects
>>> and force the user to write r[i, ] or r[, j], depending on what they want.
>>
>> FYI, I've tried out Martin's updated version at it seems like a
>> one-column raster matrix is now returned for r[i], e.g.
>
> Yes, that's what I've been looking at ...
>
>>> r<- as.raster(1:8, max=8, nrow=2, ncol=4);
>>> r
>> [,1] [,2] [,3] [,4]
>> [1,] "#202020" "#606060" "#9F9F9F" "#DFDFDF"
>> [2,] "#404040" "#808080" "#BFBFBF" "#FFFFFF"
>>
>>> r[1:length(r)]
>> [,1]
>> [1,] "#202020"
>> [2,] "#404040"
>> [3,] "#606060"
>> [4,] "#808080"
>> [5,] "#9F9F9F"
>> [6,] "#BFBFBF"
>> [7,] "#DFDFDF"
>> [8,] "#FFFFFF"
>
> ... and the above is exactly the sort of thing that will fry your mind if the image that you are subsetting is, for example, a photo.
>
Why doesn't raster behave consistently like any matrix object? I would expect simply
> r[1:length(r)]
[1] "#202020" "#404040" "#606060" "#808080" "#9F9F9F" "#BFBFBF" "#DFDFDF"
[8] "#FFFFFF"
Where it's obvious what happened. I saw the comment about the vector but I'm not sure I get it - why don't you want a vector? The raster is no different than matrices - you still need to define the dimensions when going back anyway, moreover what you get now is not consistent at all since there raster never had that dimension anyway ...
Cheers,
Simon
> Paul
>
>>> r[1:5,drop=TRUE]
>> [,1]
>> [1,] "#202020"
>> [2,] "#404040"
>> [3,] "#606060"
>> [4,] "#808080"
>> [5,] "#9F9F9F"
>> Warning message:
>> In `[.raster`(r, 1:5, drop = TRUE) :
>> 'drop' is always implicitly FALSE in '[.raster'
>>
>> Also,
>>
>>> r[1:5]<- "white"
>>> r
>> [,1] [,2] [,3] [,4]
>> [1,] "white" "white" "white" "#DFDFDF"
>> [2,] "white" "white" "#BFBFBF" "#FFFFFF"
>>
>> /Henrik
>>
>>>
>>> Paul
>>>
>>>> Thank you, Henrik, for the bug report.
>>>> Martin
>>>>
>>>> ______________________________________________
>>>> R-devel at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>> --
>>> Dr Paul Murrell
>>> Department of Statistics
>>> The University of Auckland
>>> Private Bag 92019
>>> Auckland
>>> New Zealand
>>> 64 9 3737599 x85392
>>> paul at stat.auckland.ac.nz
>>> http://www.stat.auckland.ac.nz/~paul/
>>>
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>
> --
> Dr Paul Murrell
> Department of Statistics
> The University of Auckland
> Private Bag 92019
> Auckland
> New Zealand
> 64 9 3737599 x85392
> paul at stat.auckland.ac.nz
> http://www.stat.auckland.ac.nz/~paul/
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
More information about the R-devel
mailing list