Dear Paul and others, Thanks for the quick response.
2009/9/25 Paul Murrell <p.murr...@auckland.ac.nz>: > Hi > > The bit you found that says ... > > # Write "[<-.unit" methods too ?? > > ... is the crucial bit. > When I figured that, I had already written up my email so I thought I'd ask anyway from a naive user point of view (in this regard, perhaps the help page of unit.c could mention what common methods are not available). The results I got can be quite surprising at first. > 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. I'm afraid I won't be of much help here, I merely copied and pasted the "[.unit" method with a minimal change that seemed to make it work for illustrative purposes. I don't really understand unit.arithmetic and unit in general. > 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. Either that or people have struggled to find their own workaround every time. I've recently hacked a fake matrix of unit objects, where perhaps a proper implementation would find other grateful users. (Given a list of grobs, I needed to compute rowMax and colMax of their size in a rectangular arrangement -- see example below, also as a recent post on r-help). > 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) ? > Though not as succinct as I'd like, I think the drawDetails method of tableGrob[*] might present the problem: drawDetails.table <- function(x, recording=TRUE){ # makeTableGrobs returns lists of grobs, and their width and height in a rectangular layout lg <- with(x, makeTableGrobs(as.character(as.matrix(d)), rows, cols, nrow(d), ncol(d), equal.width = equal.width, equal.height = equal.height, gpar.content = gpar.content, gpar.col = gpar.col, gpar.row = gpar.row, gpar.fill = gpar.fill, gpar.rowfill = gpar.rowfill, gpar.colfill = gpar.colfill ) ) # now I need to add some horizontal and vertical padding to each cells, # EXCEPT for the rownames and colnames if they are not to be shown # whereby I convert everything to raw values, use normal vector indexing, # and convert back to unit widthsv <- convertUnit(lg$widths + x$padding.h, "mm", valueOnly=TRUE) heightsv <- convertUnit(lg$heights + x$padding.v, "mm", valueOnly=TRUE) widthsv[1] <- widthsv[1] * as.numeric(x$show.rownames) widths <- unit(widthsv, "mm") heightsv[1] <- heightsv[1] * as.numeric(x$show.colnames) heights <- unit(heightsv, "mm") # once this is done, I can create the layout cells = viewport(name="table.cells", layout = grid.layout(lg$nrow+1, lg$ncol+1, width=widths, height=heights) ) # and place the elements pushViewport(cells) tg <- arrangeTableGrobs(lg$lgt, lg$lgf, lg$nrow, lg$ncol, lg$widths, lg$heights, padding.h = x$padding.h, padding.v = x$padding.v, separator=x$separator, show.box=x$show.box, show.csep=x$show.csep, show.rsep=x$show.rsep) upViewport() } Of course I could make the calculation of adding padding to the cells earlier in the chain (in makeTableGrobs) but it's not really its place. Best, baptiste [*]: http://code.google.com/p/gridextra/source/browse/trunk/R/tableGrob.r to be run as, either, library(grid) source("http://gridextra.googlecode.com/svn/trunk/R/grob-utils.r") source("http://gridextra.googlecode.com/svn/trunk/R/tableGrob.r") grid.table(head(iris)) or simply, Install http://gridextra.googlecode.com/files/gridextra_0.3.tar.gz library(gridextra) example(tableGrob) > 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@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 > p...@stat.auckland.ac.nz > http://www.stat.auckland.ac.nz/~paul/ > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel