Использование geom_boxplot с квантилями

#r #ggplot2

#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")
  

Это должно использовать 0% в качестве минимального, 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, поэтому я не совсем уверен, как это интерпретировать, но я предполагаю, что это из-за . in 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 значениями. Итак, это сводится к следующему: как мне получить доступ к этим 5 значениям внутри score ?

РЕШЕНИЕ

Я обнаружил проблему с моим набором данных. Как я упоминал в своем редактировании, столбцы 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 для построения графика должна быть

 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") 
  

И это отображает все идеально.

Спасибо всем за хорошие предложения, хотя они и не устранили проблему, они очень помогли разобраться.

Комментарии:

1. . Вероятно, это не проблема, но я бы поспорил % , что это так. Попробуйте прочитать ?make.names .

2. Я думал, что это хорошо, но я нашел пример, в котором p <- ggplot(data,aes(x=.id, ymin=`5%`, lower=`25%`, middle=`50%`, upper=`75%`, ymax=`95%`)) geom_boxplot(stat="identity") правильно отображались чужие данные.

3. Ну, я просто пытался подтолкнуть вас к тому, чтобы попробовать простой первый проход при отладке: установите имена столбцов на allquartile что-то абсолютно безопасное (без символов).

4. ymax='s.1000%' может быть лишнее 0 , и у вас, похоже, есть множество «и`

5. @Henry: Упс, это наверняка опечатка, но проблема все еще сохраняется. кроме того, все, что связано с именами s.x%, является обратным

Ответ №1:

На самом деле, основываясь на ваших правках, я думаю, что ваша настоящая проблема заключается в том, что вы не должны были использовать 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))
  

Комментарии:

1. Это имеет большой смысл. Я просто использую aggregate, поскольку это то, что уже было написано кем-то другим, для построения более простых вещей, таких как среднее, медианное и максимальное. Мне удалось заставить все работать, как указано выше, с помощью агрегатных и матричных операций, но я попробую сделать это. Я действительно нахожу довольно странным, что мой третий «столбец» является матрицей.

Ответ №2:

Вот как это решить. Проблема в именах ваших столбцов. Если вы введете names(allquartile) , вы заметите, что ваши имена столбцов и т.д. s.0. s.25. Я бы рекомендовал избегать всех знаков препинания в именах столбцов, за исключением _ или . .

 require(stringr)
names(allquartile) = str_replace_all(names(allquartile), "\.", '')
p <- ggplot(allquartile2, aes_string(x = "T", ymin = "s0", lower = "s25", 
      middle = "s50", upper = "s75", ymax = "s100", color = "method"))   
     geom_boxplot(stat = "identity")