From baptiste.auguie at googlemail.com  Thu Sep 24 22:19:30 2009
From: baptiste.auguie at googlemail.com (baptiste auguie)
Date: Thu, 24 Sep 2009 22:19:30 +0200
Subject: [Rd] unexpected behavior of `[<-` method for class unit.arithmetic
Message-ID: <de4e29f50909241319q3a1815fcxc1539f4f362102c7@mail.gmail.com>

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



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