在绘制 geom_bar()时避免 ggplot 对 x 轴排序

我想用 ggplot 绘制以下数据:

SC_LTSL_BM    16.8275
SC_STSL_BM    17.3914
proB_FrBC_FL   122.1580
preB_FrD_FL    18.5051
B_Fo_Sp    14.4693
B_GC_Sp    15.4986

我要做的就是做一个酒吧图,维持酒吧的秩序, (即从 SC_LTSL_BM ...B_GC_Sp开始) Ggplot geom _ bar 是用来对它们进行排序的。如何避免这种情况呢?

  library(ggplot2)
dat <- read.table("http://dpaste.com/1469904/plain/")
pdf("~/Desktop/test.pdf")
ggplot(dat,aes(x=V1,y=V2))+geom_bar()
dev.off()

目前的数字是这样的: enter image description here

90429 次浏览

You need to tell ggplot that you've got an ordered factor already, so it doesn't automatically order it for you.

dat <- read.table(text=
"SC_LTSL_BM    16.8275
SC_STSL_BM    17.3914
proB_FrBC_FL   122.1580
preB_FrD_FL    18.5051
B_Fo_Sp    14.4693
B_GC_Sp    15.4986", header = FALSE, stringsAsFactors = FALSE)


# make V1 an ordered factor
dat$V1 <- factor(dat$V1, levels = dat$V1)


# plot
library(ggplot2)
ggplot(dat,aes(x=V1,y=V2))+geom_bar(stat="identity")

enter image description here

You can also just re-order the corresponding factor as described here

x$name <- factor(x$name, levels = x$name[order(x$val)])

Here is an approach that does not modify the original data, but uses scale_x_discrete. From ?scale_x_discrete, "Use limits to adjust the which levels (and in what order) are displayed". For example:

dat <- read.table(text=
"SC_LTSL_BM    16.8275
SC_STSL_BM    17.3914
proB_FrBC_FL   122.1580
preB_FrD_FL    18.5051
B_Fo_Sp    14.4693
B_GC_Sp    15.4986", header = FALSE, stringsAsFactors = FALSE)
# plot
library(ggplot2)
ggplot(dat,aes(x=V1,y=V2))+
geom_bar(stat="identity")+
scale_x_discrete(limits=dat$V1)

enter image description here

dplyr lets you easily create a row column that you can reorder by in ggplot.

library(dplyr)
dat <- read.table("...") %>% mutate(row = row_number())
ggplot(df,aes(x=reorder(V1,row),y=V2))+geom_bar()

If you want to avoid changing the original data, then you can use fct_inorder from forcats (part of tidyverse) to keep the original order of the data along the x-axis (rather than it being changed to alphabetical).

library(tidyverse)


ggplot(dat, aes(x = fct_inorder(V1), y = V2)) +
geom_bar(stat = "identity")

Output

enter image description here

Another option with forcats is to manually specify the order with fct_relevel.

ggplot(dat, aes(
x = fct_relevel(
V1,
"SC_LTSL_BM",
"SC_STSL_BM",
"proB_FrBC_FL",
"preB_FrD_FL",
"B_Fo_Sp",
"B_GC_Sp"
),
y = V2
)) +
geom_bar(stat = "identity") +
xlab("Category")

Data

dat <- structure(list(
V1 = c(
"SC_LTSL_BM",
"SC_STSL_BM",
"proB_FrBC_FL",
"preB_FrD_FL",
"B_Fo_Sp",
"B_GC_Sp"
),
V2 = c(16.8275, 17.3914,
122.158, 18.5051, 14.4693, 15.4986)
),
class = "data.frame",
row.names = c(NA, -6L))