[Rd] R (development) changes in arith, logic, relop with (0-extent) arrays
Martin Maechler
maechler at stat.math.ethz.ch
Thu Sep 8 12:49:55 CEST 2016
>>>>> robin hankin <hankin.robin at gmail.com>
>>>>> on Thu, 8 Sep 2016 10:05:21 +1200 writes:
> Martin I'd like to make a comment; I think that R's
> behaviour on 'edge' cases like this is an important thing
> and it's great that you are working on it.
> I make heavy use of zero-extent arrays, chiefly because
> the dimnames are an efficient and logical way to keep
> track of certain types of information.
> If I have, for example,
> a <- array(0,c(2,0,2))
> dimnames(a) <- list(name=c('Mike','Kevin'),NULL,item=c("hat","scarf"))
> Then in R-3.3.1, 70800 I get
a> 0
> logical(0)
>>
> But in 71219 I get
a> 0
> , , item = hat
> name
> Mike
> Kevin
> , , item = scarf
> name
> Mike
> Kevin
> (which is an empty logical array that holds the names of the people and
> their clothes). I find the behaviour of 71219 very much preferable because
> there is no reason to discard the information in the dimnames.
Thanks a lot, Robin, (and Oliver) !
Yes, the above is such a case where the new behavior makes much sense.
And this behavior remains identical after the 71222 amendment.
Martin
> Best wishes
> Robin
> On Wed, Sep 7, 2016 at 9:49 PM, Martin Maechler <maechler at stat.math.ethz.ch>
> wrote:
>> >>>>> Martin Maechler <maechler at stat.math.ethz.ch>
>> >>>>> on Tue, 6 Sep 2016 22:26:31 +0200 writes:
>>
>> > Yesterday, changes to R's development version were committed,
>> relating
>> > to arithmetic, logic ('&' and '|') and
>> > comparison/relational ('<', '==') binary operators
>> > which in NEWS are described as
>>
>> > SIGNIFICANT USER-VISIBLE CHANGES:
>>
>> > [.............]
>>
>> > • Arithmetic, logic (‘&’, ‘|’) and comparison (aka
>> > ‘relational’, e.g., ‘<’, ‘==’) operations with arrays now
>> > behave consistently, notably for arrays of length zero.
>>
>> > Arithmetic between length-1 arrays and longer non-arrays had
>> > silently dropped the array attributes and recycled. This
>> > now gives a warning and will signal an error in the future,
>> > as it has always for logic and comparison operations in
>> > these cases (e.g., compare ‘matrix(1,1) + 2:3’ and
>> > ‘matrix(1,1) < 2:3’).
>>
>> > As the above "visually suggests" one could think of the changes
>> > falling mainly two groups,
>> > 1) <0-extent array> (op) <non-array>
>> > 2) <1-extent array> (arith) <non-array of length != 1>
>>
>> > These changes are partly non-back compatible and may break
>> > existing code. We believe that the internal consistency gained
>> > from the changes is worth the few places with problems.
>>
>> > We expect some package maintainers (10-20, or even more?) need
>> > to adapt their code.
>>
>> > Case '2)' above mainly results in a new warning, e.g.,
>>
>> >> matrix(1,1) + 1:2
>> > [1] 2 3
>> > Warning message:
>> > In matrix(1, 1) + 1:2 :
>> > dropping dim() of array of length one. Will become ERROR
>> >>
>>
>> > whereas '1)' gives errors in cases the result silently was a
>> > vector of length zero, or also keeps array (dim & dimnames) in
>> > cases these were silently dropped.
>>
>> > The following is a "heavily" commented R script showing (all ?)
>> > the important cases with changes :
>>
>> > ------------------------------------------------------------
>> ----------------
>>
>> > (m <- cbind(a=1[0], b=2[0]))
>> > Lm <- m; storage.mode(Lm) <- "logical"
>> > Im <- m; storage.mode(Im) <- "integer"
>>
>> > ## 1. -------------------------
>> > try( m & NULL ) # in R <= 3.3.x :
>> > ## Error in m & NULL :
>> > ## operations are possible only for numeric, logical or complex
>> types
>> > ##
>> > ## gives 'Lm' in R >= 3.4.0
>>
>> > ## 2. -------------------------
>> > m + 2:3 ## gave numeric(0), now remains matrix identical to m
>> > Im + 2:3 ## gave integer(0), now remains matrix identical to Im
>> (integer)
>>
>> > m > 1 ## gave logical(0), now remains matrix identical to Lm
>> (logical)
>> > m > 0.1[0] ## ditto
>> > m > NULL ## ditto
>>
>> > ## 3. -------------------------
>> > mm <- m[,c(1:2,2:1,2)]
>> > try( m == mm ) ## now gives error "non-conformable arrays",
>> > ## but gave logical(0) in R <= 3.3.x
>>
>> > ## 4. -------------------------
>> > str( Im + NULL) ## gave "num", now gives "int"
>>
>> > ## 5. -------------------------
>> > ## special case for arithmetic w/ length-1 array
>> > (m1 <- matrix(1,1,1, dimnames=list("Ro","col")))
>> > (m2 <- matrix(1,2,1, dimnames=list(c("A","B"),"col")))
>>
>> > m1 + 1:2 # -> 2:3 but now with warning to "become ERROR"
>> > tools::assertError(m1 & 1:2)# ERR: dims [product 1] do not match the
>> length of object [2]
>> > tools::assertError(m1 < 1:2)# ERR: (ditto)
>> > ##
>> > ## non-0-length arrays combined with {NULL or double() or ...} *fail*
>>
>> > ### Length-1 arrays: Arithmetic with |vectors| > 1 treated array
>> as scalar
>> > m1 + NULL # gave numeric(0) in R <= 3.3.x --- still, *but* w/
>> warning to "be ERROR"
>> > try(m1 > NULL) # gave logical(0) in R <= 3.3.x --- an *error*
>> now in R >= 3.4.0
>> > tools::assertError(m1 & NULL) # gave and gives error
>> > tools::assertError(m1 | double())# ditto
>> > ## m2 was slightly different:
>> > tools::assertError(m2 + NULL)
>> > tools::assertError(m2 & NULL)
>> > try(m2 == NULL) ## was logical(0) in R <= 3.3.x; now error as above!
>>
>> > ------------------------------------------------------------
>> ----------------
>>
>>
>> > Note that in R's own 'nls' sources, there was one case of
>> > situation '2)' above, i.e. a 1x1-matrix was used as a "scalar".
>>
>> > In such cases, you should explicitly coerce it to a vector,
>> > either ("self-explainingly") by as.vector(.), or as I did in
>> > the nls case by c(.) : The latter is much less
>> > self-explaining, but nicer to read in mathematical formulae, and
>> > currently also more efficient because it is a .Primitive.
>>
>> > Please use R-devel with your code, and let us know if you see
>> > effects that seem adverse.
>>
>> I've been slightly surprised (or even "frustrated") by the empty
>> reaction on our R-devel list to this post.
>>
>> I would have expected some critique, may be even some praise,
>> ... in any case some sign people are "thinking along" (as we say
>> in German).
>>
>> In the mean time, I've actually thought along the one case which
>> is last above: The <op> (binary operation) between a
>> non-0-length array and a 0-length vector (and NULL which should
>> be treated like a 0-length vector):
>>
>> R <= 3.3.1 *is* quite inconsistent with these:
>>
>>
>> and my proposal above (implemented in R-devel, since Sep.5) would give an
>> error for all these, but instead, R really could be more lenient here:
>> A 0-length result is ok, and it should *not* inherit the array
>> (dim, dimnames), since the array is not of length 0. So instead
>> of the above [for the very last part only!!], we would aim for
>> the following. These *all* give an error in current R-devel,
>> with the exception of 'm1 + NULL' which "only" gives a "bad
>> warning" :
>>
>> ------------------------
>>
>> m1 <- matrix(1,1)
>> m2 <- matrix(1,2)
>>
>> m1 + NULL # numeric(0) in R <= 3.3.x ---> OK ?!
>> m1 > NULL # logical(0) in R <= 3.3.x ---> OK ?!
>> try(m1 & NULL) # ERROR in R <= 3.3.x ---> change to logical(0) ?!
>> try(m1 | double())# ERROR in R <= 3.3.x ---> change to logical(0) ?!
>> ## m2 slightly different:
>> try(m2 + NULL) # ERROR in R <= 3.3.x ---> change to double(0) ?!
>> try(m2 & NULL) # ERROR in R <= 3.3.x ---> change to logical(0) ?!
>> m2 == NULL # logical(0) in R <= 3.3.x ---> OK ?!
>>
>> ------------------------
>>
>> This would be slightly more back-compatible than the currently
>> implemented proposal. Everything else I said remains true, and
>> I'm pretty sure most changes needed in packages would remain to be done.
>>
>> Opinions ?
>>
>>
>>
>> > In some case where R-devel now gives an error but did not
>> > previously, we could contemplate giving another "warning
>> > .... 'to become ERROR'" if there was too much breakage, though
>> > I don't expect that.
>>
>>
>> > For the R Core Team,
>>
>> > Martin Maechler,
>> > ETH Zurich
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
> --
> Robin Hankin
> Neutral theorist
> hankin.robin at gmail.com
> [[alternative HTML version deleted]]
More information about the R-devel
mailing list