Teraz dodamy tabelę podsumowującą nad naszą dynamiczną tabelą danych. Tabelę podsumowującą należy aktualizować zgodnie z aktywami zaznaczonymi (zwróć uwagę na liczbę mnogą, ponieważ zezwalamy na przypadek All w tej zakładce). Poświęć chwilę i zastanów się, jak sam byś to zaimplementował? Jeśli spróbujesz odtworzyć wzór pokazany wcześniej dla obiektu data, który pokazaliśmy wcześniej, uzyskasz poprawne, ale nieefektywne rozwiązanie. Powodem jest to, że logika filtrowania danych byłaby zduplikowana, co jest niepotrzebne. Aby uniknąć tej pułapki, pokażemy dalej, jak udostępniać strumienie między różnymi funkcjami reaktywnymi za pomocą funkcji reactive(), która jest funkcją, która służyła do przygotowania reaktywnych wartości dla innych funkcji reaktywnych. W tym przypadku przenosimy całą logikę, którą stworzyliśmy wcześniej, do wyrażenia przesłanego jako parametr do tej funkcji i przypisujemy ją do obiektu data , który sam jest teraz funkcją reaktywną. Zwróć uwagę, że dodaliśmy również trochę kodu, aby sprawdzić, czy bieżący wybór zasobów różni się od All, a jeśli tak, użyj tej wartości do filtrowania danych, podobnie jak filtrujemy je za pomocą dat. Gdy już to zrobimy, możemy zastąpić logikę, którą mieliśmy wewnątrz funkcji datatable(), prostym wywołaniem funkcji reaktywnej data(), która zapewni oczekiwaną ramkę danych. A teraz, gdy wyodrębniliśmy tę logikę, możemy ponownie użyć wywołania data() w innym miejscu, tak jak robimy to w obserwatorze output$summary_table utworzonym za pomocą funkcji rednerTable(). Jak widać, jest przekazywana ramka danych utworzona ze statystykami dla minimum, mediany, średniej i maksimum ramki danych zwróconej przez funkcję data(). W takim przypadku możemy zagwarantować, że dane użyte w funkcjach output$table() i output$summary_table() są takie same:
server <- function (input, output) {
data ,<- ORIGINAL_DATA
start <- input$date_range[1]
end <- input$date_range[2]
if (input$asset != „All”){
data <- data[data$name == input$asset, ]
}
if (time_to_date_string.TimeStamp(start) != DATE_MIN |
time_to_date_string.TimeStamp(end) != DATE_MAX) {
data <- data [
data$timestamp >= time_to_timestamp.TimeStamp(start) &
data$timestamp <= time_to_timestamp.TimeStamp(end), ]
}
return(data)
})
output$table <- DT::renderDataTable(DT::datatable({return(data()) }))
output$select_asset <- renderUI ({
assets <- DATA_ASSETS
if (input$tab_selected ==2)}
assets <- c(„All”, assets)
}
return(selectInput(„asset”, „Asset : „, assets))
})
output$summary_table <- renderTable(data.frame (
Minimum = min(data() $price_usd),
Median = mean(data() $price_usd),
Mean = mean(data)() $price_usd),
Max = max(data () $price_usd)
))
Zachowaj ostrożność, jeśli używasz danych stochastycznych (na przykład liczb losowych), jeśli powielasz logikę danych zamiast używać funkcji reactive(), ponieważ prawdopodobnie nie uzyskasz tych samych danych w obu miejscach. Musimy również wprowadzić odpowiednie wywołanie funkcji w obiekcie ui , które umieszczamy w odpowiednim tabPanel(). Aby umieścić w tym ramkę danych, którą właśnie utworzyliśmy, używamy funkcji tableOutput() z odpowiednim ciągiem znaków summary_table jako parametrem. Kod jest następujący (zauważ, że pomijam kod ui wokół tego fragmentu):
tabPanel (
„Data Overview”,
value = 2,
fluidRow(tableOutput(„summary_table”)),
fluidRow(DT::dataTableOutput(„table”))
)
Po wprowadzeniu tych zmian, u góry dynamicznej tabeli danych powinna pojawić się tabela podsumowująca ze wspomnianymi statystykami, które powinny zostać zaktualizowane, gdy różne wartości są wysyłane jako dane wejściowe dla dat i wyboru zasobów.