x = c(1, 2, 2, 3, 3, 3, 4, 4, 5)
x.tab = table(x)
plot(x.tab, xlim = c(0, 10), xaxp=c(0, 10, 10))
(Unfortunately, I do not have enough reputation to post image, but received graph has only tick marks 1 to 5, instead of intended 0 to 10)
Why does R just ignore xaxp? I understand that I could factor x to levels 0:10 (i.e. add x = factor(x, levels=0:10)) and that would be solution, but why doesn't parameter xaxp work as intended? And by the way how to extract frequencies as vector from x.tab without complicated magic?
You can see the source to the plot.table
method by running graphics:::plot.table
. It contains this near the end:
plot(x0, unclass(x), type = type, ylim = ylim, xlab = xlab,
ylab = ylab, frame.plot = frame.plot, lwd = lwd,
..., xaxt = "n")
localaxis <- function(..., col, bg, pch, cex, lty, log) axis(...)
if (!isFALSE(list(...)$axes))
localaxis(1, at = x0, labels = nx, ...)
So you can see that the call to the default plot method specifies no axis via xaxt = "n"
, and then it draws an axis with ticks at x0
values, which in this case are the values 1:5
.
That's not what you wanted, so what you can do is ask it not to plot axes, then draw them manually yourself, e.g.
x = c(1, 2, 2, 3, 3, 3, 4, 4, 5)
x.tab = table(x)
plot(x.tab, xlim = c(0, 10), axes = FALSE)
axis(1, xaxp=c(0, 10, 10))
axis(2)
Created on 2024-03-30 with reprex v2.1.0
Another way to do this is to make x
into a factor with levels 0 to 10, e.g. x <- factor(x, levels = 0:10)
. Then plot.table
will do almost what you want without any optional arguments. (It will include dots for the zero counts, which the code above doesn't do.)