From berger @end|ng |rom mp||b-ber||n@mpg@de  Tue Sep 24 19:31:51 2019
From: berger @end|ng |rom mp||b-ber||n@mpg@de (Hilmar Berger)
Date: Tue, 24 Sep 2019 19:31:51 +0200
Subject: [Rd] '==' operator: inconsistency in data.frame(...) == NULL
In-Reply-To: <23937.63728.859845.525356@stat.math.ethz.ch>
References: <9075d086-7945-b759-f311-765d626b7a61@mpiib-berlin.mpg.de>
 <23928.43189.410927.15494@stat.math.ethz.ch>
 <c21fa68d-00da-dcc1-6390-dce52c889748@mpiib-berlin.mpg.de>
 <f144303d-0fa6-7827-bca3-2587a43c3484@mpiib-berlin.mpg.de>
 <1bbabc36-43c8-aad6-4a08-b310d13c8938@mpiib-berlin.mpg.de>
 <94e5fbbe-6f03-9b69-8abf-ebeced33a016@mpiib-berlin.mpg.de>
 <23937.60510.182530.176708@stat.math.ethz.ch>
 <23937.63728.859845.525356@stat.math.ethz.ch>
Message-ID: <2077d941-9a2e-8acc-3125-cf10a7fe8deb@mpiib-berlin.mpg.de>

Dear Martin,

thanks a lot for looking into this. Of course you were right that the 
fix was not complete - I apologize for not having tested what I believed 
to be the solution.

My comments on the S4 classes seemed to stem from a misunderstanding on 
my side. I now believe to understand that S4 classes that inherit from R 
base object types might dispatch Ops for the same object types.

If the base object value of such S4 classes is unset and therefore 
empty, this empty value will be passed on to e.g. Ops.data.frame where 
it would trigger the same issue as e.g. logical(0).

setClass("MyClass", slots = list(x="numeric", label="character"), 
contains = "numeric")
a = new("MyClass", x=3, label="FOO")
a at .Data

 > logical(0)

a == data.frame(a=1:3)
# error

I understand that this is all as expected and the error should most 
likely disappear with the fix you submitted for other 0-extent cases.

Thanks again and best regards,

Hilmar

Am 18/09/2019 um 11:29 schrieb Martin Maechler:
>>>>>> Martin Maechler
>>>>>>      on Wed, 18 Sep 2019 10:35:42 +0200 writes:
>    >>>>> Hilmar Berger
>    >>>>>     on Sat, 14 Sep 2019 13:31:27 +0200 writes:
>
>         >> Dear all,
>         >> I did some more tests regarding the == operator in Ops.data.frame (see
>         >> below).? All tests done in R 3.6.1 (x86_64-w64-mingw32).
>
>         >> I find that errors are thrown also when comparing a zero length
>         >> data.frame to atomic objects with length>0 which should be a valid case
>         >> according to the documentation. This can be traced to a check in the
>         >> last line of Ops.data.frame which tests for the presence of an empty
>         >> result value (i.e. list() ) but does not handle a list of empty values
>         >> (i.e. list(logical(0))) which in fact is generated in those cases.
>
>         >> There  is a simple fix (see also below).
>
>      > I'm pretty sure what you write above is wrong:  For some reason
>      > you must have changed more in your own version of Ops.data.frame :
>
>      > Because there's a line
>
>      > value <- unlist(value, ...)
>
>      > there, value is *not*  list(logical(0)) there, but rather  logical(0)
>      > and then indeed, your proposed line change (at the end of Ops.data.frame)
>      > has no effect for the examples you give.
>
> On the other hand, there *is* a simple "fix" at the end of
> Ops.data.frame()  which makes all your examples "work" (i.e. not
> give an error), namely
>
> ----------------------------------------------------------------------
>
> @@ -1685,7 +1684,7 @@
>       else { ## 'Logic' ("&","|")  and  'Compare' ("==",">","<","!=","<=",">=") :
>   	value <- unlist(value, recursive = FALSE, use.names = FALSE)
>   	matrix(if(is.null(value)) logical() else value,
> -	       nrow = nr, dimnames = list(rn,cn))
> +	       nrow = nr, ncol = length(cn), dimnames = list(rn,cn))
>       }
>
> ----------------------------------------------------------------------
>
> i.e., explicitly specifying 'ncol' compatibly with the column names.
> However, I guess that this change would *not* signal errors
> where it *should* and so am *not* (yet?) proposing to "do" it.
>
> Another remark, on  S4  which you've raised several times:
> As you may know that the 'Matrix' package (part of every
> "regular" R installation) uses S4 "everywhere" and it does
> define many methods for its Matrix classes, all in source file  Matrix/R/Ops.R
> the development version (in svn / subversion) being online on R-forge here:
>
>    https://r-forge.r-project.org/scm/viewvc.php/pkg/Matrix/R/Ops.R?view=markup&root=matrix
>
> and "of course", there we define S4 group methods for Ops all
> the time, and (almost) never S3 ones...
> [[but I hope you don't want to start combining data frames
>   with Matrix package matrices, now !]]
>
> Martin Maechler
> ETH Zurich  and  R Core Team



[Rd] '==' operator: inconsistency in data.frame(...) == NULL
Hilmar Berger