проценты на у лаборатории в граненой диаграмме ggplot? - PullRequest
32 голосов
/ 18 января 2011

делая фасеты в ggplot Я часто хотел бы использовать процент вместо количества.

например,

test1 <- sample(letters[1:2], 100, replace=T)
test2 <- sample(letters[3:8], 100, replace=T)
test <- data.frame(cbind(test1,test2))
ggplot(test, aes(test2))+geom_bar()+facet_grid(~test1)

Это очень просто, но если N отличается в фасете A по сравнению с фасетом B, я думаю, было бы лучше сравнить проценты таким образом,каждый аспект суммируется до 100%.

как бы вы этого достигли?

Надеюсь, мой вопрос имеет смысл.

С уважением.

Ответы [ 6 ]

45 голосов
/ 03 сентября 2013

Вот метод в пределах ggplot, использующий ..count.. и ..PANEL..:

ggplot(test, aes(test2)) + 
    geom_bar(aes(y = (..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..])) + 
    facet_grid(~test1)

Поскольку он рассчитывается на лету, он должен быть устойчивым к изменениям параметров графика.

21 голосов
/ 18 января 2011

Попробуйте это:

# first make a dataframe with frequencies
df <- as.data.frame(with(test, table(test1,test2)))
# or with count() from plyr package as Hadley suggested
df <- count(test, vars=c('test1', 'test2'))
# next: compute percentages per group
df <- ddply(df, .(test1), transform, p = Freq/sum(Freq))
# and plot
ggplot(df, aes(test2, p))+geom_bar()+facet_grid(~test1)

alt text

Вы также можете добавить + scale_y_continuous(formatter = "percent") к графику для ggplot2 версии 0.8.9 или + scale_y_continuous(labels = percent_format()) для версии 0.9.0.

7 голосов
/ 18 января 2011

Очень простой способ:

ggplot(test, aes(test2)) + 
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    facet_grid(~test1)

Так что я изменил только параметр geom_bar на aes(y = (..count..)/sum(..count..)). После установки ylab в NULL и указания форматера вы можете получить:

ggplot(test, aes(test2)) +
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    facet_grid(~test1) +
    scale_y_continuous('', formatter="percent")

Обновление Обратите внимание, что хотя formatter = "percent") работает для ggplot2 версии 0.8.9, в 0.9.0 вам нужно что-то вроде scale_y_continuous(labels = percent_format()). alt text

1 голос
/ 18 января 2011

Вот решение, которое должно заставить вас двигаться в правильном направлении.Мне любопытно посмотреть, есть ли более эффективные способы сделать это, поскольку это кажется немного хакерским и запутанным.Мы можем использовать встроенный аргумент ..density.. для y aesthetic, но факторы там не работают.Поэтому нам также нужно использовать scale_x_discrete, чтобы соответствующим образом обозначить ось после того, как мы преобразовали test2 в числовой объект.

ggplot(data = test, aes(x = as.numeric(test2)))+ 
geom_bar(aes(y = ..density..), binwidth = .5)+ 
scale_x_discrete(limits = sort(unique(test$test2))) + 
facet_grid(~test1) + xlab("Test 2") + ylab("Density") 

Но позвольте мне вкратце рассказать мне, что вы думаете.

Кроме того, вы можете сократить создание тестовых данных примерно так, чтобы избежать лишних объектов в вашей среде и необходимости связывать их вместе:

test <- data.frame(
    test1 = sample(letters[1:2], 100, replace = TRUE), 
    test2 = sample(letters[3:8], 100, replace = TRUE)
)
0 голосов
/ 16 ноября 2015

Благодарим Вас за то, что поделились "подсказкой" ПАНЕЛИ по методу ggplot.

Для информации: вы можете получить проценты в y lab на той же гистограмме, используя count и group в методе ggplot:

ggplot(test, aes(test2,fill=test1))
   + geom_bar(aes(y = (..count..)/tapply(..count..,..group..,sum)[..group..]), position="dodge")
   + scale_y_continuous(labels = percent)
0 голосов
/ 25 января 2011

Я часто сталкиваюсь с подобными ситуациями, но использую совершенно другой подход, в котором используются два других пакета Хэдли, а именно, reshape и plyr.Прежде всего потому, что я предпочитаю смотреть на вещи как на стопроцентно уложенные бары (когда они составляют 100%).

test <- data.frame(sample(letters[1:2], 100, replace=T), sample(letters[3:8], 100, replace=T))
colnames(test) <- c("variable","value")
test <- cast(test, variable + value ~ .) 
colnames(test)[3] <- "frequ"

test <- ddply(test,"variable", function(x) {
    x <- x[order(x$value),]
    x$cfreq <- cumsum(x$frequ)/sum(x$frequ)
    x$pos <- (c(0,x$cfreq[-nrow(x)])+x$cfreq)/2
    x$freq <- (x$frequ)/sum(x$frequ)
    x
})

plot.tmp <- ggplot(test, aes(variable,frequ, fill=value)) + geom_bar(stat="identity", position="fill") + coord_flip() + scale_y_continuous("", formatter="percent")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...