I'm trying to use dotplot()
from ´lattice´ to plot a data set where categories are only present for a subset, and I'm calling scales = list(y = list(relation = "free"))
to avoid unnecessary vertical spacing. However, doing this seems to bungle up the vertical spacing between items. What more is that is seems to be related to whether or not the categories are overlapping, since it is only then that the error occurs.
library(lattice)
variables <- c(rep("Age", 4), rep("Sex", 2), rep("Children", 3))
levels <- c(1, 5, 100, 101, "Females", "Males", 2, 3, 90)
values <- rnorm(9)
dotplot(levels ~ values | variables, layout = c(1,3),
scales = list(y = list(relation = "free")))
You can clearly see that the spacing between for example 90 and 3 are off, whereas there is no issue with Males and Females. Now if I change the categories that have numerical values so that they don't overlap, I get correct spacing.
levels <- c(1:4, "Females", "Males", 5:7)
dotplot(levels ~ values | variables, layout = c(1,3),
scales = list(y = list(relation = "free")))
Does anybody know what is going on and what I can do to fix this?
You can use a function by the author of lattice
(see dotplot, dropping unused levels of 'y').
Quoting Deepayan Sarkar from that post:
"It's a bit problematic. Basically, you can use relation="free"/"sliced"
, but y behaves as as.numeric(y)
would. So, if the small subset in each panel are always more or less contiguous (in terms of the levels being close to each other) then you would be fine. Otherwise you would not. In that case, you can still write your own prepanel
and panel
functions,"
dotplot(levels ~ values | variables, layout = c(1,3),
scales = list(y = list(relation = "free")),
prepanel = function(x, y, ...) {
yy <- y[, drop = TRUE]
list(ylim = levels(yy),
yat = sort(unique(as.numeric(yy))))
},
panel = function(x, y, ...) {
yy <- y[, drop = TRUE]
panel.dotplot(x, yy, ...)
})