К сожалению, вы просите 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)
** Примечание: 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)
# 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")])
один вариант - просто преобразовать data.frame –
@Ricardo: как? Создать новый фреймворк? – user248237dfsf
точно, расплав + dcast от reshape2 –