Reorder data in ggplot (after successfully reorder

2019-07-11 04:58发布

问题:

This question already has an answer here:

  • How do you specifically order ggplot2 x axis instead of alphabetical order? [duplicate] 2 answers

After helping me out to sort my data.frame depending on a specific order, I've thought that I could label my plot axes using the the scale_x_discrete()-parameter, where I have defined the same order to fit data and labels. Although the labels are created in the right order, but it seems that ggplot orders the dataset by itself, which means that the bars do not fit with the labels.
As you can see in the screenshots, the bars are visualized in the same order (one ggplot with and one without using scale_x_discrete(limits = orderSort).... Is there any way to supress the internal ordering and to apply the order, which should be new.df$UserEmail ?

# Load packages
library(plyr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(reshape2)

# Load data
RawDataSet <- read.csv("http://pastebin.com/raw/VP6cF31A", sep=";")

# Summarising the data
new.df <- RawDataSet %>% 
  group_by(UserEmail,location,context) %>% 
  tally() %>%
  mutate(n2 = n * c(1,-1)[(location=="NOT_WITHIN")+1L]) %>%
  group_by(UserEmail,location) %>%
  mutate(p = c(1,-1)[(location=="NOT_WITHIN")+1L] * n/sum(n))

# Reorder new.df based on a defined verctor
new.df <- new.df[ order(match(new.df$UserEmail, as.integer(c("28","27","25","23","22","21","20","16","12","10","9","8","5","4","2","1","29","19","17","15","14","13","7","3","30","26","24","18","11","6")) )), ]

# Same vector which is used to sort new.df
orderSort <- c("28","27","25","23","22","21","20","16","12","10","9","8","5","4","2","1","29","19","17","15","14","13","7","3","30","26","24","18","11","6")

ggplot() +
  geom_bar(data = new.df[new.df$location == "NOT_WITHIN",],
           aes(x = UserEmail, y = n2, color = "darkgreen", fill = context),
           size = 1, stat = "identity", width = 0.7) +
  geom_bar(data = new.df[new.df$location == "WITHIN",],
           aes(x = UserEmail, y = n2, color = "darkred", fill = context),
           size = 1, stat = "identity", width = 0.7) +
  # Labels are created in the right order, but geom_bars are not sorted
  # scale_x_discrete(limits = orderSort) +
  scale_y_continuous(breaks = seq(-25,25,5),
                     labels = c(25,20,15,10,5,0,5,10,15,20,25)) +
  scale_color_manual("Location of interaction",
                     values = c("darkgreen","darkred"),
                     labels = c("NOT_WITHIN","WITHIN")) +
  scale_fill_manual("Type of interaction",
                    values = c("lightyellow","lightblue"),
                    labels = c("Clicked A","Clicked B")) +
  guides(color = guide_legend(override.aes = list(color = c("darkred","darkgreen"),
                                                  fill = NA, size = 2), reverse = TRUE),
         fill = guide_legend(override.aes = list(fill = c("lightyellow","lightblue"),
                                                 color = "black", size = 0.5))) +
  coord_flip() +
  theme_grey() +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 1, vjust = 0.5, size = 14),
    axis.title = element_blank(),
    legend.title = element_text(face = "italic", size = 14),
    legend.key.size = unit(1, "lines"),
    legend.text = element_text(size = 11))

Without using using the scale_x_discrete-paramter.

By using the scale_x_discrete-paramter.

回答1:

UPDATE: The trick is to convert the UserEmail variable to a factor variable:

# converting 'UserEmail' to a factor variable
new.df$UserEmail <- factor(as.character(new.df$UserEmail),
                           levels = unique(new.df$UserEmail))


# and use:
scale_x_discrete(limits = orderSort)

this results in the following plot:


OLD ANSWER: If I understand you correctly, you should define the breaks instead of defining the limits. Using:

scale_x_discrete(breaks = orderSort, limits = sort(unique(new.df2$UserEmail)))
# or:
scale_x_discrete(breaks = orderSort, limits = as.integer(orderSort))

gives:



标签: r ggplot2