Issue with a drawing a vertical line in ggplot for

2019-09-20 18:28发布

问题:

I have the following table. I want to plot a vertical line using the "st_date_wk" column for each county. Please see my code below but it DOES NOT draw the vertical line using the "st_date_wk" column. Cannot figure out what I am doing wrong here.

Any help is appreciated.

Thanks.

dfx1:

YEAR     Week       Area    acc_sum    percentage COUNTY st_date_wk    
1998     10-1       250     250        12.4       133    10-4
1998     10-2       300     550        29.0       133    10-4   
1998     10-3        50     600        58.0       133    10-4
1998     10-4       100     700        75.9       133    10-4
1998     10-5       100     800       100.0       133    10-4
1999     9-3         75      75        22.0       205    10-2
1999     10-1       250     250        12.4       205    10-2
1999     10-2       300     550        29.0       205    10-2   
1999     10-3        50     600        58.0       205    10-2
1999     10-4       100     700        75.9       205    10-2
1999     10-5       100     800       100.0       205    10-2
.
.

dfx1$YEAR <- as.factor(dfx1$YEAR)
dfx1$COUNTY <- as.factor(dfx1$COUNTY)
dfx1$percentage <- as.numeric(dfx1$percentage)
dfx1$acc_sum <- as.numeric(dfx1$acc_sum)
dfx1$Week <- factor(dfx1$Week, ordered = T)
dfx1$st_date_wk <- factor(dfx1$st_date_wk,ordered = T)

dfx1$Week <- factor(dfx1$Week, levels=c("6-1","6-2","6-3","6-4","6-5","7-1","7-2","7-3","7-4","7-5","8-1","8-2","8-3","8-4","8-5","9-1","9-2","9-3","9-4","9-5","10-1","10-2","10-3","10-4","10-5","11-1","11-2","11-3","11-4","11-5","12-1","12-2","12-3","12-4","12-5"))

gg <- ggplot(dfx1, aes(Week,percentage, col=YEAR, group = YEAR))
gg <- gg + geom_line()
gg <- gg + facet_wrap(~COUNTY, 2, scales = "fixed")
gg <- gg + theme(text = element_text(size=15), axis.text.x = element_text(angle=90, hjust=1))
gg <- gg + geom_vline(data=dfx1, aes(xintercept = dfx1$st_date_wk), color = "blue", linetype = "dashed", size = 1.0)+  facet_wrap(~COUNTY)

  plot(gg)

1: In Ops.ordered(x, from[1]) : '-' is not meaningful for ordered factors

回答1:

It is a very interesting issue, and I haven't quite figured out why it does not work. However, there is a fix for it.

First, This is the data that is used in the answer:

dfx1 <- read.table(text = 
                     "YEAR     Week       Area    acc_sum    percentage COUNTY st_date_wk    
                   1998     10-1       250     250        12.4       133    10-4
                   1998     10-2       300     550        29.0       133    10-4   
                   1998     10-3        50     600        58.0       133    10-4
                   1998     10-4       100     700        75.9       133    10-4
                   1998     10-5       100     800       100.0       133    10-4
                   1999     9-3         75      75        22.0       133    10-1", 
                   header = TRUE)

Convert types of Year, COUNTY, percentage, and acc_sum:

dfx1$YEAR <- as.factor(dfx1$YEAR)
dfx1$COUNTY <- as.factor(dfx1$COUNTY)
dfx1$percentage <- as.numeric(dfx1$percentage)
dfx1$acc_sum <- as.numeric(dfx1$acc_sum)

Create a vector with the week_levels (more reader-friendly):

week_levels <- c("6-1","6-2","6-3","6-4","6-5",
                 "7-1","7-2","7-3","7-4","7-5",
                 "8-1","8-2","8-3","8-4","8-5",
                 "9-1","9-2","9-3","9-4","9-5",
                 "10-1","10-2","10-3","10-4","10-5",
                 "11-1","11-2","11-3","11-4","11-5",
                 "12-1","12-2","12-3","12-4","12-5")

Transform Week and st_date_wk to an ordered factor with the same levels:

dfx1$Week <- factor(dfx1$Week, levels = week_levels, ordered = TRUE)
dfx1$st_date_wk <- factor(dfx1$st_date_wk, levels = week_levels, ordered = TRUE)

Create labels for scale_x_discrete (a named vector where the names correspond to the breaks of the x-axis):

labels <- week_levels 
names(labels) <- seq_along(week_levels)

Create the visualisation, but instead of using the factors on the x-axis, use numeric, in geom_vline() use which() to get the number that corresponds to a Week on the x-axis. Then use scale_x_discrete() to add the weeks.

library(ggplot2)

ggplot(dfx1, aes(x = as.numeric(Week), y = percentage, col=YEAR, group = YEAR)) + 
  geom_line() +
  geom_vline(xintercept = which(levels(dfx1$Week) %in% dfx1$st_date_wk), color = "blue", linetype = "dashed") +
  scale_x_continuous(breaks = seq_along(labels), labels = labels) + 
  theme(text = element_text(size=15), axis.text.x = element_text(angle=90, hjust=1)) +
  facet_wrap(~COUNTY, 2, scales = "fixed")

This will give you:

EDIT AFTER COMMENT:

library(dplyr)
dfx1 <- merge(dfx1, 
              (dfx1 %>% 
                 group_by(COUNTY, st_date_wk) %>% 
                 summarise(x = which(levels(st_date_wk) %in% st_date_wk[COUNTY == COUNTY]))),
              by = c("COUNTY", "st_date_wk"), all.x = TRUE
)

ggplot(dfx1, aes(x = as.numeric(Week), y = percentage, col=YEAR, group = YEAR)) + 
  geom_line() +
  geom_vline(data = dfx1, aes(xintercept = x), color = "blue", linetype = "dashed") +
  scale_x_continuous(breaks = seq_along(labels), labels = labels) + 
  theme(text = element_text(size=15), axis.text.x = element_text(angle=90, hjust=1)) +
  facet_wrap(~COUNTY, 2, scales = "fixed")



回答2:

You just have to change the aes in the geom_vline

aes(xintercept = dfx1$st_date_wk %>% as.numeric())


标签: r ggplot2 line