API requests
Here is a wish-list of gtable API. Sorry if I'm missing current implementation.
- get one element of gtable by name or location. maybe overriding
[[and[. - modify the one element, with several consistency check.
- remove a row/column
- replace a row/column/cell/region
will be continued.
Should I create separate issues?
So I think you can now remove a row/col with negative indexing. But I agree gtable needs more tools for working at the grob level.
Maybe gtable_width, gtable_width<-, gtable_height, gtable_height<-, gtable_modify_grob ?
The initial stab for gtable_modify_grob may be like [<-.gtable with dimension check and size adjustment.
Then,
g <- gt[1:2, 1:2]
# modify the elements of g
gt[1:2, 1:2] <- g
So I think you can now remove a row/col with negative indexing
will be useful but now negative indexing only works as row-wise or col-wise deletion.
gt <- gtable_matrix(letters[1:9], matrix(list(grob1), 3, 3), widths = unit(rep(1, 3), "null"), heights = unit(rep(1, 3), "null"))
gt[-2, -2]
Ah, this behavior is compatible with matrix:
m <- matrix(1:9, 3, 3)
m[-2, -2, drop = F]
so, what we need is an interface to remove grob from gtable, like
gt[2, 2] <- NULL
but in gtable, how should it be if multi-cell grob?
I couldn't find best solution... or may be this is unnecessary.
I think the complication is that you want to interact with the gtable on two levels: the table level and the individual grob level. Two-d indexing makes sense for the table level, but I don't think it does for the grob level (because as you pointed out how would multi-cell grobs work?)
One option would be to override [.gtable so when you used a single index it indexed into the grobs. I think this is confusing though. Another option would be create a function that worked in the same way as names, so you could go grobs(gtable)[1] <- new_grob. I think then you'd also need a layout function for modifying their position. (But then how do you keep them in sync if you want to remove a grob? Removing a group would automatically remove the corresponding layout layer?)
Then you could have a find_grob that returned a logical vector of grobs meeting your criteria and use that to index into grobs and layout. You might want to find all the grobs in a given cell, or that cross a given cell, or have a given name, ...
if I think of a gtable as a data.frame rather than a matrix, then locating (a) grob(s) is like applying subset() with t, b, l, r and/or names.
locating and removing grobs is definitely a useful feature to have, see how messy it gets in this example: https://groups.google.com/d/msg/ggplot2/87gdDq0P3x0/WZxs89AY1HwJ