【问题标题】:Singling out a particular sample for an aesthetic using ggplot使用 ggplot 从美学中挑选出特定样本
【发布时间】:2013-12-12 16:26:42
【问题描述】:

相关: Order Bars in ggplot2 bar graph。该问题涉及基于某些数字特征(例如从最大到最小)的重新排序。我想基于非数据固有的任意原因重新排序。

另外,how to change the order of a discrete x scale in ggplot?。这建议对因子水平进行排序,我已经在下面完成了,但是我似乎无法结合对数据进行子集化和保持我想要的因子顺序的行为。


我有一些产品测试数据,我想让一个特定的样本在我的条形图中脱颖而出。在我的特殊情况下,我想将我感兴趣的样本一直推到一侧并以不同的方式着色(即将突出显示的样本不按字母顺序向右移动并使其变为绿色)。

这是我尝试做的一个例子:

library(ggplot2)
test <- data.frame(names = c("A", "B", "C", "Last", "X", "Y", "Z"))
test$y <- 1:7

如果我按原样绘制,众所周知,因子将按字母顺序排列。

ggplot(test, aes(x=Names, y=y)) + geom_bar()

我重新排列了这样的关卡:

test$names <- factor(test$names, levels = test$names[ c(1:3, 5:7, 4) ])
test$names
[1] A    B    C    Last X    Y    Z   
Levels: A B C X Y Z Last

到目前为止一切顺利。如果我们现在绘制,我会得到这个,这给了我想要的顺序:

ggplot(test, aes(x=names, y=y)) + geom_bar()

但我想将Last 涂成绿色,所以我尝试了这个:

p <- ggplot(test[!test$names=="Last" ,], aes(x=names, y=y)) + geom_bar()
p <- p + geom_bar(aes(x=names, y=y), test[test$names=="Last" ,], fill="darkgreen")
p

如果我们查看传递给 ggplot 的我的原位子集:

test[!test$names=="Last" , ]$names
[1] A B C X Y Z
Levels: A B C X Y Z Last

test[!test$names=="Last" , ]$names
[1] A B C X Y Z
Levels: A B C X Y Z Last

所以级别排序是正确的,但 ggplot 没有使用它来确定绘图顺序。

我想知道问题是否是来自同一数据帧的绘图数据,所以我将它们分开,想知道 ggplot 是否会将单独的数据附加到末尾:

test2 <- test[test$names=="Last" , ]
test <- droplevels(test)
test2 <- droplevels(test2)
p <- ggplot(test, aes(x=names, y=y)) + geom_bar()
p <- p + geom_bar(aes(x=names, y=y), test2, fill="darkgreen")
p

结果和上一张图一样,中间是Last

最后,我认为这可以通过scale_x_discrete 完成,所以我尝试了这个:

p <- ggplot(test[!test$names=="Last" ,], aes(x=names, y=y)) + geom_bar()
p <- p + geom_bar(aes(x=names, y=y), test[test$names=="Last" ,], fill="darkgreen")
p <- p + scale_x_discrete(breaks=test$names[c(1:3, 5:7, 4)])
p

我仍然在中间得到Last

问题

  • 为什么 ggplot 恢复为按字母顺序绘制而不是查看因子级别顺序?
  • 是否有其他(或更好的方法)在情节中挑出一行进行“特殊处理”?

【问题讨论】:

    标签: r plot ggplot2


    【解决方案1】:

    另外两种获得你想要的东西的方法:

    1. 使用scale_x_discrete(drop=FALSE) 这是必要的,因为尽管levels() 的因子相同,但您使用的两组数据的x 值并不相同。

      p <- ggplot(test[!test$names=="Last" ,], aes(x=names, y=y)) + geom_bar()
      p <- p + geom_bar(aes(x=names, y=y), test[test$names=="Last" ,], fill="darkgreen")
      p <- p + scale_x_discrete(drop = FALSE)
      p
      
    2. 用派生的美学和地图着色(好吧,填充)

      ggplot(test, aes(x=names,  y=y, fill=(names=="Last"))) +
        geom_bar() +
        scale_fill_manual(breaks = c(FALSE,TRUE), 
                          values = c("black", "darkgreen"),
                          guide = "none")
      

    两者都给出了一个看起来就像你答案中的图表。

    【讨论】:

    • 你能扩展一下“没有相同的关卡集”吗? levels() 使用 test[criteria=="", ] 为两个数据子集提供了相同的集合。我真的很喜欢第二种解决方案。我不知道有人能做到这一点。所以填充向量最终是一个 T/F 值的向量,然后你告诉 ggplot 如何将颜色映射到 T/F?有没有办法在aes() 之外做到这一点,所以不必通过guide="none"?谢谢!
    • 我的措辞很糟糕。正如您所指出的,这些因素确实具有相同的levels()。然而,实际存在的值并不相同。至于你的第二个问题,它必须在 aes() 调用中,因为颜色/填充是由数据决定的,而不是被分配一个常数值。如果它是数据驱动的,那么它必须在 aes() 内。
    • 感谢您的解释。感觉很傻,我意识到我也可以在 df 中创建一个具有某种填充值(duh)的新向量,然后将其设置为该值。你在原地做这件事很整洁。再次感谢!
    • 最后一个(希望是)问题。 fill=aes() 之外是否只允许包含一个值?我问如果填充不是由数据决定而是由手动输入决定的,比如ggplot(dat, aes(x=x, y=y), fill=c(rep("black", 6), "darkgreen"))。这似乎不起作用,所以我想为fill= 提供特定值仅适用于1)在aes() 之外和2)仅当所有条都具有相同的值时。对吗?
    • aes() 之外,任何美学都只允许采用单个值,这将适用于图形的所有(点/条形/其他)。所以,对 1 和 2 都是肯定的。如果您指定多个值,则这些值与您的数据之间存在隐式关系; ggplot 要求这种关系是明确的(在 data.frame 中)。
    【解决方案2】:

    叹息...

    答案在上面的第二个相关问题 (how to change the order of a discrete x scale in ggplot?) 中,但进一步下降并且不被接受。手动执行此操作的方法是通过scale_x_discrete,但我认为breaks= 是正确的方法。它实际上是在使用limits=

    执行我正在寻找的正确代码是:

    p <- ggplot(test[!test$names=="Last" ,], aes(x=names, y=y)) + geom_bar()
    p <- p + geom_bar(aes(x=names, y=y), test[test$names=="Last" ,], fill="darkgreen")
    p <- p + scale_x_discrete(limits=test$names[c(1:3, 5:7, 4)])
    p
    

    或者,因为我已经重新安排了关卡:

    p <- ggplot(test[!test$names=="Last" ,], aes(x=names, y=y)) + geom_bar()
    p <- p + geom_bar(aes(x=names, y=y), test[test$names=="Last" ,], fill="darkgreen")
    p <- p + scale_x_discrete(limits=levels(test$names))
    p
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多