1

I have data as follows:

A <- structure(c(9, 7, 9, 9, 9, 8, 9, 6, 4, 7, 9, 9, 9, 8, 7, 7, 9, 
8, 8, 9, 5, 5, 8, 7, 5, 9, 9, 7, 7, 9, 8, 7, 8, 9, 4, 7, 9, 8, 
6, 7, 7, 4, 8, 6, 9, 9, 8, 1, 9, 9, 9, 8, 9, 9, 6, 7, 4, 7, 9, 
6, 6, 9, 9, 8, 6, 8, 7, 7, 7, 5, 9, 5, 7, 9, 8, 4, 9, 8, 8, 8, 
5, 8, 1, 7, 7, 5, 6, 9, 5, 9, 6, 9, 6, 9, 9, 9, 8, 9, 9, 9, 9, 
4, 6, 4, 8, 6, 8, 8, 7, 4, 6, 7, 4, 8, 8, 8, 7, 9, 3, 8, 8, 6, 
9, 8, 8, 6, 5, 8, 3, 8, 6, 8, 7, 7, 6, 9, 5, 9, 8, 7, 9, 7, 9, 
9, 8, 9, 6, 8, 9, 8, 6, 8, 9, 9, 9, 4, 8, 8, 5, 8, 7, 8, 8, 9, 
9, 6, 8, 5, 9, 8, 7, 9, 9, 7, 6, 8, 7, 7, 8, 9, 6, 7, 8, 9, 7, 
6, 6, 9, 7, 7, 8, 7, 7, 2, 4, 9, 9, 7, 7, 9, 7, 6, 9, 9, 8, 5, 
5), label = NA_character_, class = c("labelled", "numeric"))

B <- structure(c(9, 9, 9, 8, 8, 9, 6, 9, 8, 8, 6, 9, 9, 9, 6, 7, 9, 
7, 8, 9, 7, 9, 9, 8, 7, 9, 8, 7, 8, 9, 8, 9, 9, 9, 9, 7, 9, 7, 
8, 9, 7, 7, 8, 4, 6, 9, 7, 7, 9, 9, 9, 8, 9, 8, 9, 9, 4, 8, 9, 
8, 7, 9, 9, 8, 7, 8, 9, 8, 2, 7, 8, 8, 8, 8, 8, 6, 4, 9, 9, 8, 
3, 7, 3, 8, 8, 9, 7, 9, 5, 6, 7, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 
7, 3, 7, 9, 7, 7, 7, 8, 8, 9, 9, 8, 8, 9, 6, 9, 9, 6, 7, 8, 7, 
8, 9, 9, 7, 6, 8, 7, 9, 6, 5, 8, 8, 7, 9, 8, 9, 9, 7, 9, 7, 9, 
8, 7, 9, 4, 8, 7, 7, 9, 9, 9, 9, 9, 4, 9, 9, 6, 7, 6, 7, 8, 9, 
8, 9, 5, 9, 8, 8, 8, 9, 9, 6, 8, 8, 8, 8, 8, 8, 7, 8, 9, 9, 9, 
7, 4, 8, 7, 7, 9, 8, 8, 7, 5, 8, 9, 8, 8, 9, 8, 5, 8, 9, 8, 9, 
7), label = NA_character_, class = c("labelled", "numeric"))

library(ggplot2)

df <- data.frame(value = c(A, B), 
                 variable = rep(c("tax", "truth"), each = length(A)))

ggplot(df) + 
  geom_bar(aes(value, fill = variable), position = "dodge") + 
  scale_fill_manual(values = c(rgb(0,0,1,0.5), rgb(1,0,0,0.5))) + 
  theme(legend.title = element_blank(), legend.position = c(0.1, 0.85))

I would now like to add a density plot (preferably for all three variables). I found this code here, by Thiery and I tried to adapt it, but I cannot get it to work:

ggplot(df, aes(a = A)) + 
  geom_histogram(aes(y = ..density..), binwidth = 5) + 
  geom_density()

Error: Aesthetics must be either length 1 or the same as the data (414): a
Run `rlang::last_error()` to see where the error occurred.

I also found this solution:

library(MASS)    # for fitsidtr(...)
# excellent fit (of course...)
ggplot(df) + 
  geom_bar(aes(value, fill = variable), position = "dodge") + 
  scale_fill_manual(values = c(rgb(0,0,1,0.5), rgb(1,0,0,0.5))) + 
  stat_function(fun=dbeta,args=fitdistr(df$A,"beta",start=list(shape1=1,shape2=1))$estimate)
  theme(legend.title = element_blank(), legend.position = c(0.1, 0.85))

Error in fitdistr(df$A, "beta", start = list(shape1 = 1, shape2 = 1)) : 
  'x' must be a non-empty numeric vector

But I run into the same problem.

Could anyone explain to me what I am doing wrong?

Tom
  • 2,173
  • 1
  • 17
  • 44

1 Answers1

4

You actually need to set y to ..count... I only know this because I had a similar issue some months ago to make a similar plot. Code below works to add the density curve:

ggplot(df, aes(value, fill = variable)) +
    geom_density(aes(y = ..count..), size = 0.7, alpha = 0.3) +
    geom_bar(position = "dodge") + 
    scale_fill_manual(values = c(rgb(0,0,1,0.5), rgb(1,0,0,0.5))) + 
    theme(legend.title = element_blank(), legend.position = c(0.1, 0.85))

enter image description here

csgroen
  • 2,511
  • 11
  • 28
  • Thank you very much! Is there any way to force a smoother line? – Tom Jan 29 '21 at 10:02
  • 1
    There probabily is, you check check on the parameters of `geom_density` and see if there is something related to "smoothness" – csgroen Jan 29 '21 at 15:26
  • I tried haha, I think it should be `bw`. But I cannot figure out how to use it. – Tom Jan 29 '21 at 15:30
  • You can set it to a number like `bw=1` (will be smoother than this) or an option like `bw='bcv'`, which is one of the bandwith selectors supported by `stats`. You can see what each one means by looking at the `stats::bw.bcv` help file. `bcv`, for biased-CV, also gives a smoother line – csgroen Jan 29 '21 at 16:17
  • I was messing around with the abbreviations, but `bw=1` was exactly what I wanted. Thank you very much! – Tom Jan 29 '21 at 16:19