Skip to content

1.7 Interaktywne raporty WWW

zozlak edited this page Oct 25, 2016 · 8 revisions

Z pomocą pakietu rmarkdown możliwe jest zastąpienie pliku definicji odbiorców poprzez interaktywny formularz na stronie WWW. Jeśli użytkownik zmieni wartości formularza, wyświetlany raport zostanie automatycznie odświeżony na podstawie aktualnie wybranych w formularzu wartości. Aby skorzystać z tej możliwości należy:

  • Przygotować szablon raportu i plik danych, tak jak w wypadku generowania pojedynczego raportu.
  • Przygotować oddzielny szablon formularza, który zastąpi plik definicji odbiorców. Budowa tego pliku zostanie dokładnie opisana poniżej.
  • Wygenerować interaktywną stronę WWW poprzez naciśnięcie przycisku Run Document w otwartym szablonie formularza (przycisk Run Document znajduje się na pasku nad polem edycji szablonu formularza).

Szablon formularza

Szablon formularza jest to plik .Rmd, który zawiera następujące elementy:

  • Nagłówek informujący o tym, że jest to szablon formularza interaktywnego:

    ---
    title: "Tytuł strony WWW"
    runtime: shiny
    ---
    
  • Wstawkę R, a w niej:

    • Definicję pól formularza poprzez wywołanie funkcji inputPanel().
    • Opis sposobu wygenerowania raportu na podstawie wybranych przez użytkownika wartości pół formularza poprzez wywołanie funkcji renderUI().

Najłatwiej przygotowanie formularza omówić będzie na przykładzie:

  • Załóżmy, że dysponujemy szablonem raportu oraz plikiem danych, jak w przykładzie w rozdziale 1.6.1.
  • Chcemy zastąpić plik definicji odbiorców poprzez danie użytkownikowi możliwości samodzielnego wyboru odbiorcy z listy rozwijalnej. Listę taką tworzymy poprzez wywołanie
  • Do poprawnego wygenerowania raportu potrzebujemy również pozostałych danych z pliku definicji odbiorców – wartości zmiennych IdOdbiorcy oraz NazwaOdbiorcyCel dla odbiorcy wybranego przez użytkownika w formularzu. Słowniki tych wartości tych zmiennych będziemy musieli na sztywno umieścić w kodzie wywołania funkcji renderUI().

Kompletny plik formularz.Rmd będzie miał postać:

---
title: "ETAP STUDIÓW"
runtime: shiny
---
```{r, echo = FALSE, message = FALSE, warning = FALSE}
library(MLAK)

inputPanel(
  selectInput(
    'NazwaOdbiorcy', 
    label = 'Nazwa odbiorcy',
    choices = c('odbiorca X', 'odbiorca Y'),
    selected = 1
  )
)

renderUI({
  slownikNazwaOdbiorcyCel = c('odbiorca X' = 'odbiorcy X', 'odbiorca Y' = 'odbiorcy Y')
  slownikIdOdbiorcy = c('odbiorca X' = 1, 'odbiorca Y' = 2)

  NazwaOdbiorcyCel = slownikNazwaOdbiorcyCel[input$NazwaOdbiorcy]
  IdOdbiorcy = slownikIdOdbiorcy[input$NazwaOdbiorcy]

  wczytajDane('dane.csv')

  rmarkdown::render(
    input = 'szablon.Rmd', 
    output_format = html_document(),
    output_file = 'tmp.html'
  )
  raport = HTML(readLines('tmp.html'))
  unlink('tmp.html')
  return(raport)
})
```

Pierwsza część to opisany już nagłówek informującym o tym, że jest to formularz interaktywny:

---
title: "ETAP STUDIÓW"
runtime: shiny
---

Następnie następuje wstawka R, w której ładowany jest pakiet MLAK, a w dalszej kolejności wywoływane są dwie funkcje: inputPanel() – opisująca kontrolki formularza oraz renderUI() – opisująca sposób wygenerowania raportu:

```{r, echo = FALSE, message = FALSE, warning = FALSE}
library(MLAK)

inputPanel(
  (…)
)

renderUI({
  (…)
})
```

Funkcja inputPanel()

Funkcja inputPanel() przyjmuje tyle argumentów, ile jest kontrolek formularza. Każdy z tych argumentów jest wywołaniem funkcji tworzącym kontrolkę pożądanego typu (patrz http://shiny.rstudio.com/tutorial/lesson3/). W naszym przypadku jest to funkcja selectInput(), która tworzy listę rozwijalną. Przyjmuje ona jako kolejne argumenty:

  • Nazwę pola formularza – na tej podstawie nazwana zostanie zmienna dostępna w funkcji renderUI(), w której zapisany będzie wartość wybrana w tym polu formularza przez użytkownika.
  • Etykietę – tekst, który zostanie wyświetlony obok listy rozwijalnej.
  • Wektor wartości, które będą wyświetlone na liście.
  • Numer domyślnie wybranej pozycji listy.

Tak więc kod:

inputPanel(
  selectInput(
    'NazwaOdbiorcy', 
    label = 'Nazwa odbiorcy',
    choices = c('odbiorca X', 'odbiorca Y'),
    selected = 1
  )
)

tworzy formularz składający się z jednej listy rozwijalnej, z wartościami odbiorca X oraz odbiorca Y, z których domyślnie wybrana jest pierwsza. Obok listy rozwijalnej wyświetlona będzie etykieta Nazwa odbiorcy, a wartość wybrana przez użytkownika z listy dostępna będzie w funkcji renderUI() w zmiennej input$NazwaOdbiorcy.

Funkcja renderUI()

Funkcja renderUI() ma za zadanie zwrócić wygenerowany raport.

Uwaga! Wszystkie wartości wybrane przez użytkownika w formularzu są w niej dostępne na liście input, a więc jeśli nazwaliśmy pole formularza NazwaOdbiorcy (jak w omawianym przykładzie), to jego wartość dostępna jest w zmiennej input$NazwaOdbiorcy.

Ponieważ użytkownik wybiera jedynie nazwę odbiorcy, zaś do wygenerowania raportu potrzebne są jeszcze identyfikator odbiorcy w zmiennej oraz nazwa odbiorcy w celowniku w zmiennej, wewnątrz funkcji musimy ustawić wartości tych zmiennych. W tym celu:

  • Tworzymy słowniki przechowujące wartości zmiennych NazwaOdbiorcyCel oraz IdOdbiorcy dla poszczególnych odbiorców:

    slownikNazwaOdbiorcyCel = c('odbiorca X' = 'odbiorcy X', 'odbiorca Y' = 'odbiorcy Y')
    slownikIdOdbiorcy = c('odbiorca X' = 1, 'odbiorca Y' = 2)
  • Na podstawie wartości wybranej przez użytkownika, przekazanej w zmiennej input$NazwaOdbiorcy, wybieramy ze słowników właściwe wartości i przypisujemy je do zmiennych NazwaOdbiorcyCel oraz IdOdbiorcy:

    NazwaOdbiorcyCel = slownikNazwaOdbiorcyCel[input$NazwaOdbiorcy]
    IdOdbiorcy = slownikIdOdbiorcy[input$NazwaOdbiorcy]

Kolejne kroki są już zawsze takie same (zmieniają się ew. tylko ścieżki do pliku danych i szablonu raportu):

  • Wczytujemy plik danych:

    wczytajDane('dane.csv')
  • Mając ustawione wszystkie zmienne opisujące odbiorcę oraz wczytany plik danych, generujemy na podstawie szablonu raportu raport w formacie HTML. Używamy do tego funkcji render() pakietu rmarkdown:

    rmarkdown::render(
      input = 'szablon.Rmd', 
      output_format = html_document(),
      output_file = 'tmp.html'
    )
  • Wygenerowany raport zapisany jest w pliku tmp.html. Ostatni krok to odczytanie raportu z tego pliku, usunięcie pliku i zwrócenie treści raportu jako wyniku działania funkcji renderUI():

    raport = HTML(readLines('tmp.html'))
    unlink('tmp.html')
    return(raport)

Podsumowanie

Raporty w postaci interaktywnych stron WWW umożliwiają osiągnięcie istotnych korzyści:

  • Dają możliwość samodzielnego generowania indywidualnie sparametryzowanych raportów bez konieczności zdobywania specjalistycznej wiedzy (wystarczy umiejętność obsługi przeglądarki internetowej).
  • Jednocześnie zapewniają pełną separację osoby generującej raport od danych jednostkowych, na podstawie których jest on generowany.

Stworzenie raportu w postaci interaktywnej strony WWW nie jest trudne, wymaga jedynie zapoznania się ze sposobem opisywania kontrolek formularza, którymi użytkownik będzie parametryzował raport oraz przygotowania kodu w języku R, który na podstawie wybranych wartości przygotuje zmienne normalnie wczytywany z pliku definicji odbiorców.