使用带分位数的geom_boxplot

时间:2011-10-06 17:36:27

标签: r ggplot2

问题

我想使用ggplot的geom_boxplot并使用我自己的数据列作为分位数段,而不是stat_boxplot返回的数据列。

在进行一些转换后,数据如下所示:

> allquartile                                                      
      T method       s.0%      s.25%      s.50%      s.75%     s.100%                                                                                                    
1     2    LDA -196.76273 -190.38842 -184.01411 -177.63979 -171.26548                                                                                                    
2     3    LDA -171.53987 -166.16923 -160.79859 -115.28652  -69.77446                                                                                                    
3     4    LDA -161.17590 -157.61372 -149.71026 -124.68926  -69.77446                                                                                                    
4     5    LDA -194.10553 -179.83165 -175.14337 -168.46104 -159.07206 

经过大量的搜索和挖掘后,我发现我的绘图命令应如下所示:

p <- ggplot(allquartile,aes(x=T, ymin=`s.0%`, lower=`s.25%`,
                            middle=`s.50%`, upper=`s.75%`,
                            ymax=`s.100%`, color=method)) + 
     geom_boxplot(stat="identity")

这个应该使用s.0%作为min,s.25%作为较低等等。但是当我尝试显示p时,我收到以下错误:

Error in eval(expr, envir, enclos) : object 's.0%' not found                                                                                                             
Calls: print ... lapply -> is.vector -> lapply -> FUN -> eval -> eval

我也尝试使用aes_string代替aes,而我却收到此错误:

Error in aes_string(x = T, ymin = `s.0%`, lower = `s.25%`, middle = `s.50%`,  :                                                                                            
object 's.0%' not found 

我对R和ggplot2都很新,所以我不确定如何解释这个,但我假设它是因为.中的s.0%

我非常感谢有关如何解决这个问题的任何建议。

编辑:我已经挖了更多,我认为这是由于我对分位数方法的误解。我通过以下命令创建了allquartile

allquartile <-aggregate(list(s=topicquality$score), list(T=topicquality$T,method=topicquality$method),FUN=quantile,probs=seq(0, 1, .25)) 

我意识到没有名为score.0%score.25%等的。只有score列有5个值。因此,归结为:如何在score中访问这5个值?

我发现我的数据集存在问题。正如我在编辑中提到的,根据我如何形成数据框,列score.0%score.25%等不存在。例如,运行colnames(allquartile)返回:

[1] "T"      "method" "score"

事实证明,score列是值的向量。正在运行allquartile$score给了我:

            0%       25%       50%       75%       100%
[1,] -196.7627 -190.3884 -184.0141 -177.6398 -171.26548
[2,] -171.5399 -166.1692 -160.7986 -115.2865  -69.77446
[3,] -161.1759 -157.6137 -149.7103 -124.6893  -69.77446
[4,] -194.1055 -179.8316 -175.1434 -168.4610 -159.07206
[5,] -200.1544 -174.2835 -167.7209 -145.3432 -129.54586

然后我可以通过

访问每个单独的分位数值
> allquartile$score[,1]
[1] -196.7627 -171.5399 -161.1759 -194.1055 -200.1544

我不熟悉R足以知道这是什么类型的数据结构,但我称之为矩阵。与任何好的矩阵对象一样,m[,column]返回列的值,而m[row,]返回行的值,m[row, column]获取单元格值。

考虑到这一点,我意识到propper plotting命令应该是

p <- ggplot(allquartile,
            aes(x=T,
                ymin=score[,1],
                lower=score[,2],
                middle=score[,3],
                upper=score[,4], 
                ymax=score[,5], 
                color=method)) + 
     geom_boxplot(stat="identity") 

这完美地描绘了一切。

感谢大家提出的好建议,即使他们没有解决问题,他们帮助我们解决了很多问题。

2 个答案:

答案 0 :(得分:0)

以下是如何解决它。问题出在您的列名称上。如果您输入names(allquartile),您会注意到您的列名称为s.0.s.25.等。我的建议是避免列名中的所有标点符号,除_或{ {1}}。

.

答案 1 :(得分:0)

实际上,根据您的修改,我认为您真正的问题是您不应该使用aggregate。如果您正在应用的函数返回多个值(例如quantile),则aggregate会以默认情况下以您观察到的稍微不方便的格式返回结果。

这是怎么回事。数据框有点令人困惑,实际上是一个列表,每列都是列表的一个元素。唯一的要求是每个“列”具有相同的行数。所以你得到的数据框有三个“列”:第三列只是一个矩阵!

可以使用aggregate执行此操作,但有更方便的工具。 (例如,您可以调用cbind(allquartile[,1:2],allquartile[,3])来创建“正确”维度的数据框。)

例如,非常受欢迎的一个是来自ddply包的plyr。以下是使用一些组成数据的示例,但遵循数据的一般结构:

topicquality <- data.frame(score = runif(20),
                            T = rep(letters[1:2],each = 10),
                            method = rep(letters[3:4],length.out = 20))

ddply(topicquality,.(T,method),FUN = function(x,...){quantile(x$score,...)},probs = seq(0,1,0.25))

您会注意到这将返回您期望的维度的数据框,但您仍然需要处理不方便的列名称。在你应用于每件作品的功能中,这是最好的处理:

myQuantile <- function(x,...){
    tmp <- quantile(x,...)
    names(tmp) <- NULL #Or something else convenient
    tmp
}
ddply(topicquality,.(T,method),FUN = myQuantile,probs = seq(0,1,0.25))