Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Barplot with 2 variables, 2 y-axis

Tags:

graph

plot

r

I have the following data

test<-data.frame(group=1:10, var.a=rnorm(n=10,mean=500,sd=20), var.b=runif(10))

I would like a barplot with 2 y axis (one for var.a, one for var.2). Each group (x axis, 1:10) should have 2 bars next to each other, one for var.a and one for var.b.

I cannot use one y-axis because of the difference morder of magnitude of var.a and var.b

Is this possible with base R?

Thank you

like image 208
ECII Avatar asked Feb 22 '23 01:02

ECII


1 Answers

To use the graphics package in R, one could create new variables as the values in var.a and var.b converted into proportions of the maximum values in the respective variable:

test <- data.frame(group = 1:10, var.a = rnorm(n = 10, mean = 500, sd = 20),
  var.b = runif(10))

funProp <- function(testCol) {
    test[, testCol]/max(test[, testCol])
}

test$var.a.prop <- funProp("var.a")
test$var.b.prop <- funProp("var.b")

Then draw the plot using barplot() without the axes:

barplot(t(as.matrix(test[, c("var.a.prop", "var.b.prop")])), beside = TRUE,
  yaxt = "n", names.arg = test$group)

Then add the axes on the left and the right using the original value ranges for the labels (the labels argument) and the proportional value ranges to place the labels on the axes (the at argument) (this part is not pretty, but it gets the job done):

axis(2, at = seq(0, max(test$var.a.prop), length.out = 10),
  labels = round(seq(0, max(test$var.a), length.out = 10)))

axis(4, at = seq(0, max(test$var.b.prop), length.out = 10),
  labels = round(seq(0, max(test$var.b), length.out = 10), 2))

(Sorry for the lack of an image)

EDIT:

To get the axes a bit prettyer,

myLeftAxisLabs <- pretty(seq(0, max(test$var.a), length.out = 10))
myRightAxisLabs <- pretty(seq(0, max(test$var.b), length.out = 10))

myLeftAxisAt <- myLeftAxisLabs/max(test$var.a)
myRightAxisAt <- myRightAxisLabs/max(test$var.b)

barplot(t(as.matrix(test[, c("var.a.prop", "var.b.prop")])),
  beside = TRUE, yaxt = "n", names.arg = test$group,
  ylim=c(0, max(c(myLeftAxisAt, myRightAxisAt))))

axis(2, at = myLeftAxisAt, labels = myLeftAxisLabs)

axis(4, at = myRightAxisAt, labels = myRightAxisLabs)
like image 122
BenBarnes Avatar answered Mar 08 '23 14:03

BenBarnes