Home > Software engineering >  R hist default xlim?
R hist default xlim?

Time:04-06

I am writing an R function that calls hist. hist takes an optional argument xlim that defaults to (per the documentation) range(breaks). However, as you might expect, when I call hist(..., xlim=range(breaks),...), R complains that breaks isn't found.

The issue here is that I would like for my function calls_hist to ALSO accept an optional argument xlim. However, it seems that whatever my default argument for xlim is, I can't simply pass it down to hist.

I could do some logic workarounds here to ultimately accomplish my goal, but I'm pretty sure that there's a better way. What is the "real" default argument to xlim?

CodePudding user response:

This is relatively complex.

When you call hist, which is an S3 generic, it dispatches the method hist.default. If you did not specify breaks, then breaks defaults to "Sturges". This argument is matched inside the body of hist.default, and the function nclass.Sturges is called on your x variable to generate an appropriate integer number of breaks. This number is then passed on the function pretty to determine the actual breaks. The range of this vector is taken as the default xlim.

So the "real" default method of calculating xlim given a vector x is:

predict_xlim <- function(x) range(pretty(range(x), n = nclass.Sturges(x)))

We can try this on some random samples to see if it works:

set.seed(1)

vec1 <- rnorm(1000)
vec2 <- rexp(1000)
vec3 <- runif(1000)

If we have the xlims correct, then the following code should put vertical red lines at the extreme edges of the outer histogram breaks (and hence the limits of the x axis):

hist(vec1)
lims <- predict_xlim(vec1)
lims
#> [1] -3.5  4.0
abline(v = lims, col = 'red')

hist(vec2)
lims <- predict_xlim(vec2)
lims
#> [1] 0.0 7.5
abline(v = lims, col = 'red')

hist(vec3)
lims <- predict_xlim(vec3)
lims
#> [1] 0 1
abline(v = lims, col = 'red')

So, to answer your question, you can define your function like this:

draw_a_histogram <- 
  function(x, xlim = range(pretty(range(x), n = nclass.Sturges(x))), ...) {
    hist(x, xlim = xlim, ...)
  } 

This allows you to call your function without xlim

draw_a_histogram(rnorm(500))

Or with a specified xlim

draw_a_histogram(rnorm(500), xlim = c(-1, 1))

Created on 2022-04-05 by the reprex package (v2.0.1)

  •  Tags:  
  • r
  • Related