Shiny$ 샤이니에서 여러개의 plot을 한번에 내보내는 팁
by Youngjun Na
shiny
를 사용하다 보면 하나의 *Output
과 하나의 render*
함수가 짝을 이뤄 동작하는 것을 볼 수 있습니다. 대부분 한 짝의 함수당 한개의 plot을 뱉는데 경우에 따라 여러개의 plot을 한꺼번에 표시하고 싶을 때가 있습니다. 콘솔에서 분석을 할 경우 plot을 그리는 함수를 작성하고 lapply()
또는 purrr::map()
함수를 이용하면 간단한(?) 일이지만 샤이니에서는 하나하나 *Output
과 render*
함수의 짝을 맞줘 줄 수 있는 노릇도 아닙니다. 이번 글에서는 이것을 가능하게 하는 팁을 공유하고자 합니다.
TL;DR
- 샤이니에서 여러개의 plot을 한번에 내보내고 싶으면
htmlOutput("container")
output$container <- renderUI()
do.call(tagList, map(data, function))
ui
일단 패키지 불러오기와 함께 가장 간단한 ui를 만들어 보겠습니다.
library(shiny)
library(highcharter)
library(tidyr)
library(dplyr)
library(purrr)
ui <- fluidPage(
htmlOutput("container")
)
server
데이터는 어벤져스 주인공들의 능력치입니다. 지극히 주관적인 마음으로 능력을 매겼으니 혹시 팬분들이 컴플레인을 제시하신다면 수정하도록 하겠습니다. 하지만 블랙위도우의 sexy 능력치가 100임은 양보할 수 없습니다.
먼저 plot을 그리는 함수를 작성합니다.
highcharter
패키지를 이용해 radar plot을 그려보았습니다.데이터와 plot을 그리는 함수를
lapply()
또는purrr::map()
을 이용해 여러개의 plot을 생성합니다.이를
do.call()
함수를 이용해tagList
를 생성합니다.요것들을
ui
의htmlOutput
으로 보냅니다.
server <- function(input, output, session) {
output$container <- renderUI({
# 1. 데이터 ----
hero <- data.frame(
name = c("Iron man", "Thor", "Hulk", "Captain America", "Hawkeye", "Quicksilver", "Black Widow", "Dr. Strange"),
power = c(50, 80, 100, 50, 40, 30, 30, 30),
speed = c(60, 70, 50, 50, 40, 100, 30, 10),
magic = c(10, 80, 10, 10, 10, 10, 10, 100),
mental = c(90, 50, 10, 100, 90, 30, 70, 100),
sexy= c(90, 10, 10, 30, 10, 10, 100, 20)
)
# 2. 함수 ----
creat_hc <- function(hero_name) {
hero %>%
filter(name == hero_name) %>%
tidyr::gather(key = "Statics", value = "Value", power:sexy) %>%
hchart("line", hcaes(x = "Statics", y = "Value"), height = 30) %>%
hc_chart(polar = TRUE) %>%
hc_xAxis(title = "", categories = c("power", "speed", "magic", "mental", "sexy")) %>%
hc_yAxis(title = "", max = 100, min = 0) %>%
hc_plotOptions(
line = list(
color = "white"
)
) %>%
hc_title(text = hero_name) %>%
hc_add_theme(hc_theme_superheroes())
}
# 3. lapply OR map ----
hc_result <- purrr::map(hero$name, creat_hc)
# 4. do.call ----
do.call(tagList, hc_result)
})
}
shinyApp(ui, server)
Subscribe via RSS