ggplot отображает только верхние X бары (в командах ggplot из-за Shiny) - PullRequest
0 голосов
/ 19 апреля 2020

Я искал этот ответ, но не смог его найти. Я хотел бы показать только первые X элементов графика ggplot, кодируя только в самом ggplot. Позвольте мне объяснить немного дальше. У меня есть набор данных с указанием количества жителей в городе, за каждый год (1999-2018), пол, гражданство и квартал / район города. Я выбираю один год и одно гражданство, а затем строю график количества жителей (ось Y, столбцы с разбивкой по полу для мужчин и женщин) для каждого квартала, отсортированного по количеству жителей.

Это пример: Построение резидентов для каждого квартала, «Афганистан», год 2018

Я просто хотел бы сократить до первых X (например, 10) баров. Я должен вставить код в Shinyapp, поэтому я пытаюсь вставить инструкции непосредственно среди кода в функции «манипулировать» здесь ниже. Есть ли способ сделать это в функциях aes / reorder (см. Код ниже)?

В этом коде я попытался (безуспешно) использовать функцию "subset", чтобы вырезать no. жителей (с разбивкой по кварталам, но с разбивкой по полу, т. е. я хочу сохранить четверть, где женщин 8, а мужчин 7).

Большое спасибо!

p10 <- manipulate(
  ggplot(subset(df_tothab_STR_citt[df_tothab_STR_citt$Y==YearList &
                              df_tothab_STR_citt$Citt==CittList,]), 
         aes(x = reorder(Nil, Residenti, FUN = sum),
             y = Residenti,
             group = Gen,
             fill = Gen)) + 
    geom_bar(stat = "identity") +
    scale_fill_brewer(palette = "Set1") +
    ggtitle(paste(CittList, "-", YearList)) +
    coord_flip() +
    labs(fill="Gender", x="Nil", y="Resident") +
    theme_bw(),
  CittList = picker(
    as.list(unique(as.character(df_tothab_STR_citt$Citt)))),
  YearList = picker(
    as.list(unique(as.character(sort(df_tothab_STR_citt$Y)))))
)

Это также "голова" и "str" ​​набора данных.

head(df_tothab_STR_citt)
     Y                    Nil     Gen        Citt Residenti
1 2018                 Baggio Femmine Afghanistan         2
2 1999             Bande Nere Femmine Afghanistan         1
3 2000             Bande Nere Femmine Afghanistan         1
4 2001             Bande Nere Femmine Afghanistan         1
5 2002             Bande Nere Femmine Afghanistan         1
6 2014 Buenos Aires - Venezia Femmine Afghanistan         1
str(df_tothab_STR_citt)
'data.frame':   196703 obs. of  5 variables:
 $ Y        : int  2018 1999 2000 2001 2002 2014 2016 2017 2018 2012 ...
 $ Nil      : chr  "Baggio" "Bande Nere" "Bande Nere" "Bande Nere" ...
 $ Gen      : Factor w/ 2 levels "Femmine","Maschi": 1 1 1 1 1 1 1 1 1 1 ...
 $ Citt     : chr  "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
 $ Residenti: int  2 1 1 1 1 1 1 1 1 3 ...

-------- Редактирование ------------- Ради для полноты, я опубликую здесь, что я сделал в приложении Shiny, чтобы заставить это работать для одного из графиков, которые я строю в приложении.

По сути, «реактивная» функция вычисляет df13_react на основе ввода $ что-то, что приходит от ползунков или выбора входов. Затем renderPlot / ggplot фильтрует результаты вычислений, основываясь только на диапазоне соотношений (опять же, от минимальных / максимальных ползунков между 0 и 100%)

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

С уважением.

  # PLOT13:
  output$t13 <- renderText({
    "Citizens (ITA/STR) by Nil, gender (M/F) and year (selectable)"
  })

  df13_react <- reactive({
    df13 <- df_tothab[df_tothab$Y==input$YearList,]
    # df13Nil <- unique(df_tothab$Nil[df_tothab$Residenti>input$minRes13])

    df13agg <- aggregate(df13$Residenti,
                         by=list(Nil=df13$Nil, Cittadinanza=df13$Citt),
                         FUN=sum)
    colnames(df13agg)[3]<-"Residenti"
    df13agg <- dcast(df13agg, Nil ~ Cittadinanza, value.var="Residenti")
    df13agg[is.na(df13agg)] <- 0
    df13agg$Ratio <- df13agg$STR / (df13agg$STR+df13agg$ITA)
    df13agg[is.na(df13agg)] <- 0
    df13$Ratio <- NA

    addRatio <- function (df13, df13agg){
      vRatio <- rep(0, length(df13$Ratio))
      for(i in 1:length(df13$Ratio)){
        vRatio[i] <- df13agg$Ratio[df13agg$Nil==df13$Nil[i]]
      }
      vRatio
    }
    df13$Ratio <- addRatio(df13, df13agg)
    return(df13)
  })

  output$p13 <- renderPlot({
    df13 <- df13_react()
    ggplot(df13[df13$Ratio >= input$minRatio13 / 100 &
                  df13$Ratio <= input$maxRatio13 / 100,],
           aes(x = reorder(Nil, Ratio),
               y = Residenti,
               group = interaction(Gen, Cittadinanza),
               fill = interaction(Gen, Cittadinanza))) + 
      geom_bar(stat = "identity", position = "fill") +
      scale_fill_manual(values=c("red","green",
                                 "blue","turquoise4")) +
      ggtitle(paste(input$YearList)) +
      labs(fill="Legend", x=NULL, y="Resident") +
      scale_y_continuous(labels = scales::percent_format(accuracy = 5L),
                         breaks = c(seq(0, 1, 0.1))) +
      coord_flip() +
      theme(panel.ontop = TRUE,
            panel.background = element_blank(),
            panel.grid = element_line(colour = "black"))
  })

1 Ответ

0 голосов
/ 20 апреля 2020

Похоже, код, который у вас уже есть, генерирует нужный вам график, поэтому вы просто ищете способ сократить количество наблюдений, чтобы оно было "верхним X", верно?

Простой ответ для этого может быть сначала (1) отсортировать ваш фрейм данных ("Residenti" из вида ваших данных), а затем (2) построить подмножество этого фрейма через head(df, x).

Так что-то вроде :

sorted.df <- your.df[order(Residenti, decreasing = TRUE),]
ggplot(data=subset(head(sorted.df, top.X)), aes(...)) + ...
...