更改离散x刻度的顺序

时间:2010-07-15 08:11:17

标签: r ggplot2 r-faq

我正在使用具有离散x刻度的ggplot制作一个躲闪条形图,x轴现在按字母顺序排列,但我需要重新排列它以便按y轴的值排序(即,最高的酒吧位于左侧。)

我尝试了排序或排序,但结果是对x轴进行排序,而不是分别对条形图进行排序。

我做错了什么?

6 个答案:

答案 0 :(得分:175)

对我而言,最好的方法是使用带有类别的向量,我需要limits参数scale_x_discrete。我认为这是非常简单明了的解决方案。

ggplot(mtcars, aes(factor(cyl))) + 
  geom_bar() + 
  scale_x_discrete(limits=c(8,4,6))

enter image description here

答案 1 :(得分:96)

尝试在x轴上手动设置因子的级别。例如:

library(ggplot2)
# Automatic levels
ggplot(mtcars, aes(factor(cyl))) + geom_bar()    

ggplot of the cars dataset with factor levels automatically determined

# Manual levels
cyl_table <- table(mtcars$cyl)
cyl_levels <- names(cyl_table)[order(cyl_table)]
mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels)
# Just to be clear, the above line is no different than:
# mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8"))
# You can manually set the levels in whatever order you please. 
ggplot(mtcars, aes(cyl2)) + geom_bar()

ggplot of the cars dataset with factor levels reordered manually

詹姆斯在答案中指出,reorder是重新排序因子水平的惯用方法。

mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x)))
ggplot(mtcars, aes(cyl3)) + geom_bar()

ggplot of the cars dataset with factor levels reordered using the reorder function

答案 2 :(得分:37)

您可以使用reorder

qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar")

修改

要拥有左边最高的酒吧,你必须使用一点点kludge:

qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
   data=mtcars,geom="bar")

我希望这也有负面的高度,但事实并非如此,所以它有效!

答案 3 :(得分:25)

Hadley一直在开发一个名为forcats的软件包。这个包使这项任务变得更加容易。当您想要通过因子的频率更改x轴的顺序时,可以利用fct_infreq()。对于此帖子中的mtcars示例,您希望按每个级别的频率重新排序cyl的级别。最常出现的级别保留在左侧。您所需要的只是fct_infreq()

library(ggplot2)
library(forcats)

ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
geom_bar() +
labs(x = "cyl")

如果您想要反过来,可以使用fct_rev()fct_infreq()

ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
geom_bar() +
labs(x = "cyl") 

enter image description here

答案 4 :(得分:2)

我意识到这是旧的,但也许我创建的这个功能对那里的人有用:

order_axis<-function(data, axis, column)
{
  # for interactivity with ggplot2
  arguments <- as.list(match.call())
  col <- eval(arguments$column, data)
  ax <- eval(arguments$axis, data)

  # evaluated factors
  a<-reorder(with(data, ax), 
             with(data, col))

  #new_data
  df<-cbind.data.frame(data)
  # define new var
  within(df, 
         do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a)))
}

现在,使用此功能,您可以使用ggplot2进行交互式绘图,如下所示:

ggplot(order_axis(df, AXIS_X, COLUMN_Y), 
       aes(x = AXIS_X_o, y = COLUMN_Y)) +
        geom_bar(stat = "identity")

可以看出,order_axis函数创建了另一个数据框,其中一个新列名为相同但最后有一个_o。这个新列的级别按升序排列,因此ggplot2会自动按该顺序绘制。

这有点受限(仅适用于字符或因子和列的数字组合以及按升序排列)但我仍然发现它非常适合在旅途中进行绘图。

答案 5 :(得分:0)

@Yuriy Petrovskiy's answer 如果您事先知道要绘制的级别,那就太好了。如果您不这样做(例如,因为您不想绘制数据中不存在的级别),请考虑使用 limit 函数 来指定顺序:

library(ggplot2)

my_order <- as.character(c(8,3,4,5,6))    # the `as.character` calls are only
ggplot(mtcars, aes(as.character(cyl))) +  # necessary for the OP's example
  geom_bar() +
  scale_x_discrete(limits = function(x) my_order[my_order %in% x])

来自 scale_x_discrete 的文档:

<块引用>

limits
其中之一:
- NULL 使用默认比例值
- 定义比例可能值及其顺序的字符向量
- 接受现有(自动)值并返回新值的函数

否则你的图表会变成这样(可能更可取):

ggplot(mtcars, aes(as.character(cyl))) +
  geom_bar() +
  scale_x_discrete(limits = my_order)