Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

r - geom_vline vertical line on x-axis with categorical data: ggplot2

I have data that is ordered in classes, as described in this article: https://www.r-bloggers.com/from-continuous-to-categorical/ This makes it easier to see which values are common. After creating those classes I want to create a barchart with the frequency of the different classes, which I do with the following exemplary code:

set.seed(1)
df.v <- data.frame(val = rnorm(1000, mean(4, sd=2)))
df.v$val.clss <- cut(df.v$val, seq(min(df.v$val), max(df.v$val), 1))
p1 <- ggplot(data = df.v)+
  geom_bar(aes(val.clss))
plot(p1)

What I can not figure out, is how to add a vertical line exactly between the two bars around 4, so the line is perfectly at the x-axis value. I have found this article, but this did not help me: How to get a vertical geom_vline to an x-axis of class date? Any help is appreciated. Maybe I am too new to adapt the solution to my data.frame, if so, please excuse the question.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you know the labels for the two bars you want the line to go between, you can convert their locations to numbers (the factor that they are mapped to), then pass that:

myLoc <- 
  (which(levels(df.v$val.clss) == "(2.99,3.99]") +
     which(levels(df.v$val.clss) == "(3.99,4.99]")) / 
  2


p1 +
  geom_vline(aes(xintercept = myLoc))

If it is skipping groups, you should probably make sure that all levels of the factor are plotted. When you have binned continuous data, it is best not to drop intermediate levels.

p1 +
  geom_vline(aes(xintercept = myLoc)) +
  scale_x_discrete(drop = FALSE)

Alternatively, you could drop the missing levels from the data all together (prior to plotting and to calculating myLoc):

df.v <- droplevels(df.v)

Then it will only include the that would be plotted.

As a final option, you could just use geom_histogram which does the binning automatically, but leaves the data on the original scale, which would make adding a line easier.

ggplot(df.v
       , aes(val)) +
  geom_histogram(binwidth = 1) +
  geom_vline(xintercept = 4)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...