From paul at stat.auckland.ac.nz  Thu Feb  3 01:00:36 2011
From: paul at stat.auckland.ac.nz (Paul Murrell)
Date: Thu, 03 Feb 2011 13:00:36 +1300
Subject: [Rd] [.raster bug {was "str() on raster objects fails .."}
In-Reply-To: <AANLkTikgSiucEMzfSa2s9YTypkqzYLCab9gJvkGyr0Pz@mail.gmail.com>
References: <AANLkTimycPK-3_mj5OPd0eLauAh41r2-Wkrp7j2jo1sw@mail.gmail.com>	<19783.49835.494142.88222@stat.math.ethz.ch>	<4D48A96B.9020801@auckland.ac.nz>	<AANLkTimRBZbzgRfAkE2-VhnFmVRkWz1-cCqeD4VW7O42@mail.gmail.com>	<4D48B08A.40302@auckland.ac.nz>	<5251E963-8D1C-46CF-AAB9-39ABFE520229@r-project.org>
	<AANLkTikgSiucEMzfSa2s9YTypkqzYLCab9gJvkGyr0Pz@mail.gmail.com>
Message-ID: <4D49F024.6090906@stat.auckland.ac.nz>

Hi

Martin Maechler wrote:
> On Wed, Feb 2, 2011 at 23:30, Simon Urbanek <simon.urbanek at r-project.org> wrote:
>> 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
> 
> I agree that this would be the most "logical" and notably least
> surprising behavior,
> which I find the most important argument
> (I'm sorry my last message was cut off as it was sent accidentally
> before being finished completely).

I think this behaviour might surprise some ...

download.file("http://cran.r-project.org/Rlogo.jpg",
               "Rlogo.jpg")
library(ReadImages)
logo <- read.jpeg("Rlogo.jpg")

rLogo <- as.raster(logo)
rLogoBit <- rLogo[50:60, 50:60]

library(grid)
# Original image
grid.raster(rLogoBit)
grid.newpage()
# Subset produces a vector
grid.raster(rLogoBit[1:length(rLogoBit)])

Paul

> Martin
> 
> 
>>> 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
>>>>>>
>>>>>> ______________________________________________

-- 
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/



[Rd] [.raster bug {was "str() on raster objects fails .."}
Paul Murrell