2013-07-07 4 views
3

Я делаю серию графиков плотности с geom_density из dataframe, и показывая его условия использования facet_wrap, как в:нормализующие плотности ggplot2 с facet_wrap в R

ggplot(iris) + geom_density(aes(x=Sepal.Width, colour=Species, y=..count../sum(..count..))) + facet_wrap(~Species) 

Когда я делаю это, у- оси, по-видимому, не представляет процентов каждого Species в панели, а скорее процентов всех полных данных по всем видам.

Мой вопрос: Как я могу сделать это так ..count.. переменная geom_density относится к графу элементов в каждом Species наборе каждой панели, так что панель virginica имеет ось у соответствующего «Фракция virginica точки данных "?

Кроме того, есть ли способ получить ggplot2 для вывода значений, которые он использует для ..count.. и sum(..count..), чтобы я мог проверить, какие номера он использует?

редактировать: Я не понял geom_density он выглядит даже для одного Species, ..count../sum(..count..) не процент:

ggplot(iris[iris$Species == 'virginica',]) + geom_density(aes(x=Sepal.Width, colour=Species, y=..count../sum(..count..))) + facet_wrap(~Species) 

поэтому мой пересмотрела вопрос: как я могу получить график плотности быть доля данные в каждом ящике? Должен ли я использовать stat_density для этого или geom_histogram? Я просто хочу, чтобы ось y была равна проценту/доле данных.

+0

один вариант - просто преобразовать data.frame –

+0

@Ricardo: как? Создать новый фреймворк? – user248237dfsf

+0

точно, расплав + dcast от reshape2 –

ответ

5

К сожалению, вы просите ggplot2, чтобы определить отдельные y для каждой грани, что синтаксически не может сделать AFAIK.

Так, в ответ на ваше упоминание в комментариях нить, что вы «просто хотите гистограмму принципиально», я бы предложил вместо использования geom_histogram или, если вы неравнодушны к линии вместо баров, geom_freqpoly:

ggplot(iris, aes(Sepal.Width, ..count..)) + 
    geom_histogram(aes(colour=Species, fill=Species), binwidth=.2) + 
    geom_freqpoly(colour="black", binwidth=.2) + 
    facet_wrap(~Species) 

enter image description here

** Примечание: geom_freqpoly работает так же хорошо на месте geom_histogram в моем примере выше. Я просто добавил оба в одном сюжете ради эффективности.

Надеюсь, это поможет.

EDIT: Хорошо, мне удалось разработать быстрый и грязный способ получить то, что вы хотите. Для этого необходимо установить и загрузить plyr. Извините заранее; это, вероятно, не самый эффективный способ сделать это с точки зрения использования ОЗУ, но он работает.

Во-первых, давайте ирис в открытую (я использую RStudio, так что я привык видеть все свои объекты в окне):

d <- iris 

Теперь мы можем использовать ddply для подсчета количества люди, принадлежащие к каждому уникальному измерению того, что станет вашей осью x (здесь я использовал Sepal.Length вместо Sepal.Width, чтобы дать себе немного больше диапазона, просто для того, чтобы увидеть большую разницу между группами при построении).

new <- ddply(d, c("Species", "Sepal.Length"), summarize, count=length(Sepal.Length)) 

ddply Обратите внимание, что автоматически сортирует выходной data.frame в соответствии с цитируемым переменными.

Затем мы можем разделить данные. В каждый из его уникальных условий - в случае радужной оболочки, каждый из трех видов (я уверен, что есть намного более плавный путь для этого, и если вы работаете с очень большими объемами данных, это не рекомендуется продолжать создавать подмножества же data.frame, потому что вы могли бы максимум из объема оперативной памяти) ...

set <- new[which(new$Species%in%"setosa"),] 
ver <- new[which(new$Species%in%"versicolor"),] 
vgn <- new[which(new$Species%in%"virginica"),] 

... и использовать ddply снова рассчитать пропорции лиц, подпадающих под каждое измерение, но отдельно для каждого вида.

prop <- rbind(ddply(set, c("Species"), summarize, prop=set$count/sum(set$count)), 
       ddply(ver, c("Species"), summarize, prop=ver$count/sum(ver$count)), 
       ddply(vgn, c("Species"), summarize, prop=vgn$count/sum(vgn$count))) 

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

new$prop <- prop$prop 
rm(list=ls()[which(!ls()%in%c("new", "d"))]) 

И мы можем сделать нашу фигуру с определенными пропорциями на y. Обратите внимание, что теперь я использую geom_line, так как ddply автоматически заказал ваш файл data.frame.

ggplot(new, aes(Sepal.Length, prop)) + 
    geom_line(aes(colour=new$Species)) + 
    facet_wrap(~Species) 

facet_wrap with facet-specific proportions

# let's check our work. each should equal 50 
sum(new$count[which(new$Species%in%"setosa")]) 
sum(new$count[which(new$Species%in%"versicolor")]) 
sum(new$count[which(new$Species%in%"versicolor")]) 

#... and each of these should equal 1 
sum(new$prop[which(new$Species%in%"setosa")]) 
sum(new$prop[which(new$Species%in%"versicolor")]) 
sum(new$prop[which(new$Species%in%"versicolor")]) 
+0

Я думаю, что вы правы, и это freqpoly ... Я думал .. Плотность .. делает это, но это все еще плотность, а не фракция – user248237dfsf

+0

Да, хотя freqpoly все еще только дает вы считаете. Как я уже сказал, если вы хотите получить долю, то, о чем вы, по сути, просите, это рассчитать ваши дробные значения y с другим знаменателем для каждой грани, что, по моему мнению, невозможно в ggplot2. –

+0

ах я вижу.Это то, что я хочу, хотя бы для разных фасет. Должен ли я вручную подсчитать это? как это можно сделать? – user248237dfsf

0

Может быть, используя таблицу() и barplot() вы могли бы получить то, что вам нужно. Я до сих пор не уверен, если это то, что вы после ...

barplot(table(iris[iris$Species == 'virginica',1])) 

С ggplot2

tb <- table(iris[iris$Species == 'virginica',1]) 
tb <- as.data.frame(tb) 
ggplot(tb, aes(x=Var1, y=Freq)) + geom_bar() 
0

Передача аргумента scales='free_y' в facet_wrap() должен сделать трюк.

Смежные вопросы