Hilmar Berger
2019-Sep-11 11:26 UTC
[Rd] '==' operator: inconsistency in data.frame(...) == NULL
Sorry, I can't reproduce the example below even on the same machine. However, the following example produces the same error as NULL values in prior examples: > setClass("FOOCLASS", +????????? representation("list") + ) > ma = new("FOOCLASS", list(M=matrix(rnorm(300), 30,10))) > isS4(ma) [1] TRUE > data.frame(a=1:3) == ma Error in matrix(unlist(value, recursive = FALSE, use.names = FALSE), nrow = nr,? : ? length of 'dimnames' [2] not equal to array extent Best, Hilmar On 11/09/2019 12:24, Hilmar Berger wrote:> Another example where a data.frame is compared to (here non-null, > non-empty) non-atomic values in Ops.data.frame, resulting in an error > message: > > setClass("FOOCLASS2", > ???????? slots = c(M="matrix") > ) > ma = new("FOOCLASS2", M=matrix(rnorm(300), 30,10)) > > > isS4(ma) > [1] TRUE > > ma == data.frame(a=1:3) > Error in eval(f) : dims [product 1] do not match the length of object [3] > > As for the NULL/logical(0) cases I would suggest to explicitly test > for invalid conditions in Ops.data.frame and generate a comprehensible > message (e.g. "comparison is possible only for atomic and list types") > if appropriate. > > Best regards, > Hilmar > > > On 11/09/2019 11:55, Hilmar Berger wrote: >> >> In the data.frame()==NULL cases I have the impression that the fact >> that both sides are non-atomic is not properly detected and therefore >> R tries to go on with the == method for data.frames. >> >> From a cursory check in Ops.data.frame() and some debugging I have >> the impression that the case of the second argument being non-atomic >> or empty is not handled at all and the function progresses until the >> end, where it fails in the last step on an empty value: >> >> matrix(unlist(value, recursive = FALSE, use.names = FALSE), >> ??? nrow = nr, dimnames = list(rn, cn)) >-- Dr. Hilmar Berger, MD Max Planck Institute for Infection Biology Charit?platz 1 D-10117 Berlin GERMANY Phone: + 49 30 28460 430 Fax: + 49 30 28460 401 E-Mail: berger at mpiib-berlin.mpg.de Web : www.mpiib-berlin.mpg.de
Hilmar Berger
2019-Sep-14 11:31 UTC
[Rd] '==' operator: inconsistency in data.frame(...) == NULL
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). There are other issues with the S4 class example (i.e. data.frame() == <s4_object with representation as list>) which fails for different reasons. ############################################################################## d_0 = data.frame(a = numeric(0)) # zero length data.frame d_00 = data.frame(numeric(0)) # zero length data.frame without names names(d_00) <- NULL # remove names to obtain value being an empty list() at the end of Ops.data.frame d_3 = data.frame(a=1:3) # non-empty data.frame m_0 = matrix(logical(0)) # zero length matrix #------------------------ # error A: # Error in matrix(if (is.null(value)) logical() else value, nrow = nr, dimnames = list(rn,? : # length of 'dimnames' [2] not equal to array extent d_0 == 1?? # error A d_00 == 1? # <0 x 0 matrix> d_3 == 1?? # <3 x 1 matrix> d_0 == logical(0) # error A d_00 == logical(0) # <0 x 0 matrix> d_3 == logical(0) # error A d_0 == NULL # error A d_00 == NULL # <0 x 0 matrix> d_3 == NULL # error A m_0 == d_0? # error A m_0 == d_00 # <0 x 0 matrix> m_0 == d3?? # error A # empty matrix for comparison m_0 == 1 # < 0 x 1 matrix> m_0 == logical(0) # < 0 x 1 matrix> m_0 == NULL # < 0 x 1 matrix> # All errors above could be solved by changing the last line in Ops.data.frame from # matrix(if (is.null(value)) logical() else value, nrow = nr, dimnames = list(rn, cn)) # to # matrix(if (length(value)==0) logical() else value, nrow = nr, dimnames = list(rn, cn)) # Alternatively or in addition one could add an explicit test for data.frame() == NULL if desired and raise an error ######################################################################################### # non-empty return value but failing in the same code line due to incompatible dimensions. # should Ops.data.frame at all be dispatched for <data.frame> == <S4 object> ? setClass("FOOCLASS", ????????? representation("list") ) ma = new("FOOCLASS", list(M=matrix(rnorm(300), 30,10))) isS4(ma) d_3 == ma # error A ########################################################################################## Best regards, Hilmar Am 11/09/2019 um 13:26 schrieb Hilmar Berger:> Sorry, I can't reproduce the example below even on the same machine. > However, the following example produces the same error as NULL values > in prior examples: > > > setClass("FOOCLASS", > +????????? representation("list") > + ) > > ma = new("FOOCLASS", list(M=matrix(rnorm(300), 30,10))) > > isS4(ma) > [1] TRUE > > data.frame(a=1:3) == ma > Error in matrix(unlist(value, recursive = FALSE, use.names = FALSE), > nrow = nr,? : > ? length of 'dimnames' [2] not equal to array extent > > Best, > Hilmar > > > On 11/09/2019 12:24, Hilmar Berger wrote: >> Another example where a data.frame is compared to (here non-null, >> non-empty) non-atomic values in Ops.data.frame, resulting in an error >> message: >> >> setClass("FOOCLASS2", >> ???????? slots = c(M="matrix") >> ) >> ma = new("FOOCLASS2", M=matrix(rnorm(300), 30,10)) >> >> > isS4(ma) >> [1] TRUE >> > ma == data.frame(a=1:3) >> Error in eval(f) : dims [product 1] do not match the length of object >> [3] >> >> As for the NULL/logical(0) cases I would suggest to explicitly test >> for invalid conditions in Ops.data.frame and generate a >> comprehensible message (e.g. "comparison is possible only for atomic >> and list types") if appropriate. >> >> Best regards, >> Hilmar >> >> >> On 11/09/2019 11:55, Hilmar Berger wrote: >>> >>> In the data.frame()==NULL cases I have the impression that the fact >>> that both sides are non-atomic is not properly detected and >>> therefore R tries to go on with the == method for data.frames. >>> >>> From a cursory check in Ops.data.frame() and some debugging I have >>> the impression that the case of the second argument being non-atomic >>> or empty is not handled at all and the function progresses until the >>> end, where it fails in the last step on an empty value: >>> >>> matrix(unlist(value, recursive = FALSE, use.names = FALSE), >>> ??? nrow = nr, dimnames = list(rn, cn)) >> >
Martin Maechler
2019-Sep-18 08:35 UTC
[Rd] '==' operator: inconsistency in data.frame(...) == NULL
>>>>> 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. Note also that your analysis -- treating all 0-extent data frames or matrices the same -- is very incomplete. A 0 x 0 matrix is not the same as a 0 x 1 matrix etc, and similar for data frames. Here's an extended "testing" script which takes into account some of the above : ##----------------------------------------------------------- d0 <- data.frame(a = numeric(0)) # zero length data.frame d00 <- unname(d0) # zero length data.frame __without names__ d3 <- data.frame(a=1:3) # non-empty data.frame d30. <- d3[,FALSE] # 3 x 0 -- take into account, too ! d30 <- unname(d30.) m01. <- matrix(,0,1, dimnames=list(NULL,"a")) # 0 x 1 matrix with dimnames m01 <- unname(m01.) m00. <- matrix(,0,0, dimnames=list(NULL,NULL)) # 0 x 0 matrix with dimnames m00 <- unname(m00.) m3 <- data.matrix(d3) ##------------------------ ## error A: ## Error in matrix(if (is.null(value)) logical() else value, nrow = nr, dimnames = list(rn, : ## length of 'dimnames' [2] not equal to array extent d0 == 1 # error A d00 == 1 # <0 x 0 matrix> d30. == 1 # <3 x 0 matrix> d30 == 1 # <3 x 0 matrix> d3 == 1 # <3 x 1 matrix> d0 == logical(0) # error A d00 == logical(0) # <0 x 0 matrix> d30. == logical() # <3 x 0 matrix> d30 == logical() # <3 x 0 matrix> d3 == logical(0) # error A d0 == NULL # error A d00 == NULL # <0 x 0 matrix> d30. == NULL # <3 x 0 matrix> d30 == NULL # <3 x 0 matrix> d3 == NULL # error A m00 == d0 # error A m00 == d00 # <0 x 0 matrix> m00 == d3 # error A # 0-length matrix for comparison : identical(m00., m00. == 1) ## 0 x 0 matrix *with* "invisible" dimnames [ NULL, NULL ] identical(m00., m00. == logical(0)) identical(m00., m00. == NULL) identical(m00, m00 == 1) ## 0 x 0 matrix w/o dimnames identical(m00, m00 == logical(0)) identical(m00, m00 == NULL) ## 0 x 1 --------------------- identical(m01., m01. == 1) # < 0 x 1 matrix> *with* dimnames identical(m01., m01. == logical(0)) # " " " identical(m01., m01. == NULL) # " " " identical(m01, m01 == 1) # < 0 x 1 matrix> w/o dimnames identical(m01, m01 == logical(0)) # < 0 x 1 matrix> identical(m01, m01 == NULL) # < 0 x 1 matrix> ##----------------------------------------------------------- Best regards, Martin
Possibly Parallel Threads
- '==' operator: inconsistency in data.frame(...) == NULL
- '==' operator: inconsistency in data.frame(...) == NULL
- '==' operator: inconsistency in data.frame(...) == NULL
- Crash after (wrongly) applying product operator on S4 object that derives from list
- Crash after (wrongly) applying product operator on S4 object that derives from list