Making sense of the rlnorm() function in R

log-normal

Post by Malte Möser and Matthew Salganik

There’s an activity in Bit by Bit: Social Research in the Digital Age that requires generating random draws from a log-normal distribution.  Unfortunately, the rlnorm() function in R doesn’t work exactly how many people expect.  So, we wanted to write a little post about it.  That way, if you are working on the activity—which is about power analysis—you can focus on power analysis and not the rlnorm() function.


Let’s imagine that you wanted to generate one million draws from a log-normal distribution with a mean of 7 and a standard deviation of 75.

We’ll start by setting the seed so that this analysis is reproducible.

set.seed(123)

You might try:

draws1 <- rlnorm(n = 1000000, mean = 7, sd = 75)

But, what you would find is that this doesn’t quite do what you want.

Screenshot 2016-12-20 21.15.47.png

Then, you might look at the help file for rlnorm() and try this:

draws2 <- rlnorm(n = 1000000, meanlog = log(7), sdlog = log(75))

Unfortunately, that doesn’t do what you want either.

Screenshot 2016-12-20 21.22.49.png

The problem here is that, by definition, the logarithm of the log-normal distribution follows a normal distribution with the mean and standard deviation we just specified. Essentially, rlnorm(n = 1000000, meanlog = 7, sdlog = 75) and exp(rnorm(n = 1000000, mean = 7, sd = 75)) produce the same result.

To get a sample of random data that follows a log-normal distribution and has arithmetic mean of 7 and a standard deviation of 75, you need to reparameterize things.  Roughly, you need to figure out what parameters should go into to the normal distribution such that when you exponentiate the draws, you end up with a mean of 7 and a standard deviation of 75.  Fortunately, that algebra has already been done and you can find the result on Wikipedia.  Here’s how you do it:

m <- 7
s <- 75
location <- log(m^2 / sqrt(s^2 + m^2))
shape <- sqrt(log(1 + (s^2 / m^2)))
print(paste("location:", location))
print(paste("shape:", shape))
draws3 <- rlnorm(n=1000000, location, shape)

Screenshot 2016-12-20 21.51.50.png

log-normal.png

If you want to try, here’s a file with all the steps.      And, if you would like to read more about the problem that requires this, check out the activities in Chapter 4.

One thought on “Making sense of the rlnorm() function in R

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s