Подтвердить что ты не робот

Процент на y lab в гранжевом барграфе ggplot?

Выполнение граней в ggplot Мне часто нравился процент, который будет использоваться вместо count.

например.

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%.

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

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

С уважением.

4b9b3361

Ответ 1

Попробуйте следующее:

# 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.

Ответ 2

Вот метод внутри ggplot, используя ..count.. и ..PANEL..:

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

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

Ответ 3

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

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

Ответ 4

Вот решение, которое должно заставить вас двигаться в правильном направлении. Мне любопытно узнать, есть ли более эффективные способы сделать это, поскольку это кажется немного взломанным и запутанным. Мы можем использовать встроенный аргумент ..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)
)

Ответ 5

Я встречаюсь с подобными ситуациями довольно часто, но использую совсем другой подход, который использует два других пакета Hadley, а именно reshape и plyr. В первую очередь потому, что я предпочитаю смотреть на вещи как на 100% сложенные бары (когда они составляют 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")

Ответ 6

Спасибо, что поделились подсказкой PANEL по методу 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)