I think I've found the problem, and a sort of fix, for this issue.
It appears in the panel.barchart function
each of the clauses in the function has a set of lines roughly like:
groups - as.numeric(groupSub(groups, ...))
vals - sort(unique(groups))
nvals - length(vals)
col - rep(col, length = nvals)
border - rep(border, length = nvals)
lty - rep(lty, length = nvals)
lwd - rep(lwd, length = nvals)
height - box.ratio/(1 + nvals * box.ratio)
if (reference)
panel.abline(v = origin, col = reference.line$col,
lty = reference.line$lty, lwd = reference.line$lwd)
for (i in unique(y)) {
ok - y == i
nok - sum(ok, na.rm = TRUE)
panel.rect(x = rep(origin, nok), y = (i + height *
(groups[ok] - (nvals + 1)/2)), col = col[groups[ok]],
border = border[groups[ok]], lty = lty[groups[ok]],
lwd = lwd[groups[ok]], height = rep(height,
nok), width = x[ok] - origin, just = c(left,
centre))
}
Which sets the parameter lty (and others) to NA in the example below.
D = data.frame(X=1, Y=factor(letters[2], letters[1:2]))
barchart(~ X, D, groups=Y)
This (NA) is because:
groups=[1] b
Levels: a b
thus the code then does
groups==2
vals==2
nvals==1
ok==TRUE
hence
groups[ok] == 2
but
length(lwd) == 1
thus
lwd[groups[ok]] == lwd[2] == NA
This is due to the mistaken assumption that the numeric component of
groups must be a subset of the 1:length(groups), when in fact it can
be a subset of 1:length(levels(groups)).
a silly fix:
replacing
groups - as.numeric(groupSub(groups, ...))
vals - sort(unique(groups))
nvals - length(vals)
with
nvals - length(levels(groups))
groups - as.numeric(groupSub(groups, ...))
fixes my example, but it clearly short of a full solution.
This example causes the same error, with a different situation.
Q = data.frame(X=c(NaN, 1), Y=factor(letters[1:2], letters[1:2]))
barchart(~ X, Q, groups=Y)
-Alex Brown
panel.barchart.fixed =
function (x, y, box.ratio = 1, horizontal = TRUE, origin = NULL,
reference = TRUE, stack = FALSE, groups = NULL, col = if (is.null
(groups)) plot.polygon$col else superpose.polygon$col,
border = if (is.null(groups)) plot.polygon$border else
superpose.polygon$border,
lty = if (is.null(groups)) plot.polygon$lty else
superpose.polygon$lty,
lwd = if (is.null(groups)) plot.polygon$lwd else
superpose.polygon$lwd,
...)
{
if (!is.null(groups) !is.factor(groups))
groups - factor(groups)
keep - (function(x, y, groups, subscripts, ...) {
!is.na(x) !is.na(y) if (is.null(groups))
TRUE
else !is.na(groups[subscripts])
})(x = x, y = y, groups = groups, ...)
if (!any(keep))
return()
x - as.numeric(x[keep])
y - as.numeric(y[keep])
plot.polygon - trellis.par.get(plot.polygon)
superpose.polygon - trellis.par.get(superpose.polygon)
reference.line - trellis.par.get(reference.line)
groupSub - function(groups, subscripts, ...) groups[subscripts
[keep]]
if (horizontal) {
if (is.null(groups)) {
if (is.null(origin)) {
origin - current.panel.limits()$xlim[1]
reference - FALSE
}
height - box.ratio/(1 + box.ratio)
if (reference)
panel.abline(v = origin, col = reference.line$col,
lty = reference.line$lty, lwd = reference.line$lwd)
panel.rect(x = rep(origin, length(y)), y = y, height =
rep(height,
length(y)), width = x - origin, border = border,
col = col, lty = lty, lwd = lwd, just = c(left,
centre))
}
else if (stack) {
if (!is.null(origin) origin != 0)
warning(origin forced to 0 for stacked bars)
nvals - length(levels(groups))
groups - as.numeric(groupSub(groups, ...))
col - rep(col, length = nvals)
border - rep(border, length = nvals)
lty - rep(lty, length = nvals)
lwd - rep(lwd, length = nvals)
height - box.ratio/(1 + box.ratio)
if (reference)
panel.abline(v = origin, col = reference.line$col,
lty = reference.line$lty, lwd = reference.line$lwd)
for (i in unique(y)) {
ok - y == i
ord - sort.list(groups[ok])
pos - x[ok][ord] 0
nok - sum(pos, na.rm = TRUE)
if (nok 0)
panel.rect(x = cumsum(c(0, x[ok][ord][pos][-nok])),
y = rep(i, nok), col =