[Rd] unexpected behavior of `[<-` method for class unit.arithmetic

Paul Murrell p.murrell at auckland.ac.nz
Fri Sep 25 01:39:48 CEST 2009


Hi

The bit you found that says ...

# Write "[<-.unit" methods too ??

... is the crucial bit.

Would it be possible to add such a method?

Almost certainly, it just needs someone to repeatedly bug the person who 
can make the change :)   Thanks for the suggestion for code BTW;  I'll 
take a look at that.

In the meantime, the fact that this has only come up once before, while 
surprising, suggests that people may have written code in a different 
style.  Can you give a succinct example that demonstrates a situation 
where you want to assign to a subset of a unit (rather than, say, 
calculating values, setting some to 0, then building a unit from the 
values) ?

Paul


baptiste auguie wrote:
> Dear list,
> 
> Consider the following,
> 
> library(grid)
> 
> w = unit.c(unit(1, "in"), unit(2, "in"))
> w2 = w + unit(1, "mm")
> 
> w[2] <- 0
> w2[2] <- 0
> 
> convertUnit(w, "mm")
> #[1] 25.4mm 0mm
> convertUnit(w2, "mm")
> #Error in grid.Call("L_convert", x, as.integer(whatfrom),
> as.integer(whatto),  :
> #  INTEGER() can only be applied to a 'integer', not a 'NULL'
> 
> The last line fails, as the naive replacement has destroyed the
> structure of w2 instead of having assigned a value of 0 to the second
> unit element.
> 
> I've also tried,
> 
> w = unit.c(unit(1, "in"), unit(2, "in"))
> w2 = w + unit(1, "mm")
> w2[[2]][2] <- 0
> 
> but this time, if the structure is licit, it's the result that's not
> as I intended:
> 
> convertUnit(w2,"mm")
> #[1] 26.4mm 1mm
> 
> My limited understanding is that an object of class unit.arithmetic is
> waiting until the last moment to actually perform its operation,
> stored in a tree-like structure. With this premise, I can't think of a
> good way to modify one element of a list of unit elements.
> 
> As a workaround, I can only think of the following hack where the
> objects are forced to be evaluated,
> 
> w = unit.c(unit(1, "in"), unit(2, "in"))
> w2 = convertUnit(w + unit(1, "mm"), "mm", valueOnly=TRUE)
> w2[2] <- 0
> w2 <- unit(w2, "mm")
> 
> but it clearly isn't a very desirable route.
> 
> What is the recommended way to modify one element of a unit vector?
> 
> Digging in grid/R/unit.R , I found the following comment,
> 
> # Write "[<-.unit" methods too ??
> 
> which probably explains the above. Would it be possible to add such a method,
> 
> "[<-.unit.list" <- function(x, index, value, top=TRUE, ...) {
>   this.length <- length(x)
>     index <- (1L:this.length)[index]
> 
>   if (top && any(index > this.length))
>     stop("Index out of bounds (unit list subsetting)")
>   cl <- class(x)
>   result <- unclass(x)
>   result[(index - 1) %% this.length + 1] <- value
>   class(result) <- cl
>   result
> }
> 
> a = unit.c(unit(1,"mm"),unit(2,"in"))
> a[2] <- unit(3,"in")
> a
> 
> but for unit.arithmetic also?
> 
> Regards,
> 
> baptiste
> 
> sessionInfo()
> R version 2.9.2 (2009-08-24)
> i386-apple-darwin8.11.1
> 
> locale:
> en_GB.UTF-8/en_GB.UTF-8/C/C/en_GB.UTF-8/en_GB.UTF-8
> 
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  grid      methods
> [8] base
> 
> ______________________________________________
> 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/



More information about the R-devel mailing list