Настройка эстетики граненой гистограммы

Я пытаюсь сделать некоторый анализ недавнего проекта MLB с некоторыми ggplots в R

selection <- draft[c("Team","Division","Position")]
head(selection)

  Team   Division Position
1  pit NL Central        P
2  sea AL West           P
3  ari NL West           P
4  bal AL East           P
5  kc  AL Central        O
6  was NL East           I

где P = питчер, O = аутфилд и т. д.

Я хочу показать количество игроков, выбранных командой по позиции в каждом дивизионе

p <- ggplot(data=selection, aes(x=Team, fill= Position))  + geom_bar(position="stack")
p <-  p + coord_flip()
p <- p+ ylab("Players Selected")
p <- p + facet_wrap(~Division)
p

Это дает мне часть пути, но очень непривлекательно

а) группы работают, но все команды отображаются в сетке каждого дивизиона - хотя на самом деле только 5 или 6 команд в каждом дивизионе - и правильно - отображают данные

б) При переворачивании координат команды перечислены в обратном алфавитном порядке вниз по странице. могу ли я прибегнуть. Еще неплохо было бы оставить обоснование

c) Как мне установить легенду на Pitching, Outfield, а не на P и O - это вектор, который мне каким-то образом нужно установить и включить?

d) Также было бы интересно увидеть долю выбора каждой команды, посвященную каждому типу игроков. Это достигается установкой position= "fill". Могу ли я установить оси в%, а не от 0 до 1. Я также попытался установить geom_vline (aes (xintercept = 0,5) - и yintercept на случай, если учитывается флип, - но линия не появилась на полпути по оси x

Помощь очень ценится


person pssguy    schedule 09.06.2011    source источник
comment
Если ваша цель состоит в том, чтобы просто поменять местами факторы, вы можете использовать reorder(Team, -as.numeric(Team)) в вызове aes ggplot2 для x=.   -  person Brandon Bertelsen    schedule 06.08.2011


Ответы (2)


редактировать: полное обновление, включая информацию из другого ответа, после получения данных (и сохранения их в текстовом файле с именем mlbtmp.txt) и еще нескольких экспериментов:

selection <- read.table("mlbtmp.txt",skip=1)
names(selection) <- c("row","League","Division","Position","Team")
## arrange order/recode factors
selection <- transform(selection,
       Team=factor(Team,levels=rev(levels(Team))),
                   Position=factor(Position,levels=c("P","I","C","O"),
                                  labels=c("Pitching","Infield",
                                    "Center","Outfield")))

Я поиграл с различными перестановками facet_grid, facet_wrap, scales, coord_flip и т. д. Некоторые работали, как и ожидалось, некоторые нет:

library(ggplot2)
p <- ggplot(data=selection, aes(x=Team, fill= Position))  +
  geom_bar(position="stack")
p + facet_grid(.~Division,scales="free_x") + coord_flip()  ## OK

## seems to fail with either "free_x" or "free_y"
p + facet_grid(Division~.,scales="free") + coord_flip()

## works but does not preserve 'count' axis:
p + facet_wrap(~Division,scales="free")

Я закончил с facet_wrap(...,scales="free") и использовал ylim для ограничения осей.

p + facet_wrap(~Division,scales="free") + coord_flip() +
  ylim(0,60) + opts(axis.text.y=theme_text(hjust=0))

mlb1

В принципе, можно было бы использовать ..density.., ..ncount.., ..ndensity.. или любую другую статистику, вычисляемую stat_bin, вместо ..count.. по умолчанию, но я не смог найти подходящей комбинации.

Вместо этого (что часто является лучшим решением, когда вы застряли с преобразованиями «на лету» ggplot) я сам изменил данные:

## pull out Team identification within Division and League
stab <- unique(subset(selection,select=c(Team,Division,League)))
## compute proportions by team
s2 <- melt(ddply(selection,"Team",function(x) with(x,table(Position)/nrow(x))))
## fix names
s2 <- rename(s2,c(variable="Position",value="proportion"))
## merge Division/League info back to summarized data
s3 <- merge(s2,stab)

p2 <- ggplot(data=s3, aes(x=Team, fill= Position,y=proportion))  +
  geom_bar(position="stack")+scale_y_continuous(formatter="percent")+
  geom_hline(yintercept=0.5,linetype=3)+ facet_wrap(~Division,scales="free") +
  opts(axis.text.y=theme_text(hjust=0))+coord_flip()

mlb2

Очевидно, что здесь можно было бы сделать немного больше прикрас, но это должно помочь вам в этом...

person Ben Bolker    schedule 09.06.2011
comment
a) Отображает правильные данные, но ось Team показывает только пять команд для первого дивизиона. - person pssguy; 09.06.2011
comment
Если вы включите большую часть своих данных с помощью dput(), нам будет легче вам помочь. - person joran; 09.06.2011
comment
Хм. Можете ли вы опубликовать небольшое, но достаточно полное подмножество данных (например, воспроизводимый пример) либо с помощью dput, либо разместив данные где-нибудь в Интернете и опубликовав URL-адрес? (Я пропустил комментарий Джорана, который в основном идентичен) - person Ben Bolker; 10.06.2011
comment
Не знаком с dput(), но попробую с помощью. В противном случае я, вероятно, могу опубликовать некоторые данные в Интернете. - person pssguy; 10.06.2011
comment
попробуйте эту ссылку для получения данных - person pssguy; 10.06.2011
comment
@pssguy, dput делает наши дела приятными и легкими. dput(mydata) заставит консоль выдать что-то вроде structure(list(...etc...)). Он разъясняет структуру ваших данных, а также содержание. Если вы скопируете и вставите вывод dput(selection) в свой вопрос, мы сможем вставить его в нашу консоль, чтобы получить ваш фрейм данных. Если вывод длинный, то stackexchange поместит его в прокручиваемое текстовое поле. - person Tommy O'Dell; 11.06.2011
comment
(продолжение...) Если ваш вывод очень длинный, рассмотрите возможность случайной выборки строк, например sample(selection, 10), или подмножества, например subset(selection, Team == 'sea'). - person Tommy O'Dell; 11.06.2011
comment
Большое спасибо, Бен, фантастическая работа. Я очень ценю время и усилия, которые вы вложили в это, предоставив как общие, так и пропорциональные варианты. Только один момент на случай, если кого-то интересует фактический дата-центр, на самом деле должен быть выбран ловец. центральные полевые игроки включены в категорию аутфилдеров - person pssguy; 13.06.2011
comment
Упс. Ну что ж. (Не знаю, смогу ли я вернуться и все исправить.) - person Ben Bolker; 14.06.2011

Заполнение некоторых пробелов в ответе @Ben Bolker...

Чтобы упорядочить команды по-разному, вам нужно сохранить этот столбец как фактор. Вероятно, не будет короткого и быстрого способа указать желаемый порядок, поскольку вы, скорее всего, захотите упорядочить команды в каждом дивизионе отдельно. Это означает, что вам нужно упорядочить все команды таким образом, чтобы каждое подмножество подразделений оставалось правильно упорядоченным. Что-то вроде (это схематично, не синтаксически правильно):

selection$Team <- factor(selection$Team,
    levels=c( (AL East teams in desired order), 
              (AL Central teams in desire order), etc))

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

Выравнивание текста оси можно изменить с помощью

opts(axis.text.x=theme_text(hjust=1))

Немного отступив назад, обратите внимание, что с ggplot2 решение часто находится путем изменения ваших данных, которые используются для построения графика, а не самого графика. Это другой способ думать о вещах, но удобный, когда вы к нему привыкнете.

person joran    schedule 09.06.2011
comment
выглядит хорошо, но я не думаю, что вам на самом деле нужен упорядоченный фактор - ggplot отображает факторы в порядке их уровней, независимо от того, упорядочены они или нет ... (я не уверен в этом на 100%, но тест будет достаточно просто) - person Ben Bolker; 09.06.2011
comment
Спасибо за понимание, Джоран, особенно об изменении данных. - person pssguy; 13.06.2011