Shiny

소개

R 사용자라면 R로 인터랙티브 웹 앱을 쉽게 만들 수 있게 해주는 Shiny 패키지에 이미 익숙할 수도 있습니다.

Knitr 계산 엔진을 사용할 때 Quarto 문서에는 Shiny 구성 요소(예: 입력을 제어하는 슬라이더가 있는 플롯)를 임베드하거나, 여러 구성 요소를 포함하는 간단한 Shiny 애플리케이션을 포함할 수도 있습니다.

이 섹션에서는 Quarto에 Shiny를 통합하는 방법을 다루며, 기본적인 Shiny 사용 경험이 있다고 가정합니다. Shiny에 대해 더 알고 싶다면 https://shiny.posit.co/를 참고하세요.

아래 예시를 실행하려면 최신 버전의 rmarkdown 패키지가 필요하며, 다음과 같이 설치할 수 있습니다.

 install.packages("rmarkdown")

Hello, Shiny

예를 들어 아래 문서는 “Old Faithful” 데이터셋의 플롯과 함께 구간 수를 제어하는 슬라이더를 포함합니다.

이 예시의 소스 코드는 다음과 같습니다.

---
title: "Old Faithful"
format: html
server: shiny
---

```{r}
sliderInput("bins", "Number of bins:", 
            min = 1, max = 50, value = 30)
plotOutput("distPlot")
```

```{r}
#| context: server
output$distPlot <- renderPlot({
  x <- faithful[, 2]  # Old Faithful Geyser data
  bins <- seq(min(x), max(x), length.out = input$bins + 1)
  hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
```

이 문서와 일반적인 정적 문서의 중요한 차이점은 다음 두 가지입니다.

  1. 문서 옵션에 server: shiny를 포함해 Quarto가 문서 뒤에서 Shiny Server를 실행하도록 지시합니다.

    ---
    title: "Old Faithful"
    format: html
    server: shiny
    ---
  2. 두 번째 코드 청크에 context: server 옵션을 포함해 이 R 코드가 Shiny Server에서 실행됨을 표시합니다(일반적으로 server.R에 넣는 코드).

    ```{r}
    #| context: server
    ```

Shiny 구성 요소가 포함된 Quarto 문서의 실행과 배포는 문서 실행 문서에서 다룹니다. 그 전에 좀 더 심화된 예시를 살펴보겠습니다.

사용자 정의 레이아웃

다음은 여러 입력과 사이드바를 갖춘 애플리케이션 형태의 페이지 레이아웃을 포함하는 예시입니다.

이 예시의 소스 코드는 다음과 같습니다.

---
title: "Iris K-Means Clustering"
format: 
  html:
    page-layout: custom
server: shiny
---

```{r}
#| panel: sidebar
vars <- setdiff(names(iris), "Species")
selectInput('xcol', 'X Variable', vars)
selectInput('ycol', 'Y Variable', vars, selected = vars[[2]])
numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
```

```{r}
#| panel: fill
plotOutput('plot1')
```

```{r}
#| context: server
selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })

clusters <- reactive({
  kmeans(selectedData(), input$clusters)
})

output$plot1 <- renderPlot({
  palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
    "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))

  par(mar = c(5.1, 4.1, 0, 1))
  plot(selectedData(),
       col = clusters()$cluster,
       pch = 20, cex = 3)
  points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
```

이 예시에서 주목할 점은 다음과 같습니다.

  1. YAML front-matter에 page-layout: custom 옵션을 포함하여 콘텐츠가 가운데 정렬과 패딩 대신 전체 페이지를 차지하도록 지정합니다.
  2. 사용자 인터페이스를 정의하는 두 코드 청크에 panel: sidebarpanel: fill을 추가해 특수 패널 컨테이너로 배치되도록 합니다.
  3. 마지막 R 코드 청크에 context: server를 다시 사용하여 Shiny Server 코드임을 표시합니다.

페이지 레이아웃

어떤 인터랙티브 문서는 서술형 텍스트 사이에 Shiny 구성 요소를 포함하고, 어떤 문서는(이 예시처럼) 전체 페이지 애플리케이션일 수 있습니다. 심지어 혼합형도 가능합니다. 예를 들어 왼쪽 사이드바에 입력을 두고, 본문에는 서술을 포함하면서 출력이 섞여 있는 형태를 떠올려볼 수 있습니다.

인터랙티브 문서의 레이아웃을 관리하는 도구에 대한 자세한 내용은 구성 요소 레이아웃 문서를 참고하세요.

예시

다음은 Shiny를 사용하는 Quarto 문서의 배포된 예시입니다.

예제 소스 설명
Old Faithful Code 문서의 본문 흐름에 인터랙티브 플롯을 포함하는 방법을 보여줍니다.
K-Means Code 더 “애플리케이션 같은” 페이지 레이아웃(사이드바와 메인 패널)을 사용하는 방법을 보여줍니다.
Diamonds Code 입력을 배치하는 다른 방식(페이지 하단의 세 열)을 보여줍니다.

더 알아보기

Shiny 인터랙티브 문서에 대해 더 알고 싶다면 다음 문서를 참고하세요.

  • 문서 실행: RStudio와 명령줄에서 인터랙티브 문서를 실행하는 방법과 최종 사용자에게 배포하는 방법을 다룹니다.

  • 실행 컨텍스트: 서로 다른 코드 블록(예: 렌더링 vs. 서빙)이 언제 실행되는지와, 반응성이 더 좋은 문서를 위해 비용이 큰 계산을 캐시하는 방법을 자세히 설명합니다.

  • 외부 리소스: 문서에 포함한 리소스(CSS, JS, 이미지 등)를 Shiny가 찾을 수 있도록 하는 방법을 설명합니다.

  • 구성 요소 레이아웃: 문서 안에서 인터랙티브 구성 요소를 배치하는 다양한 기법을 정리합니다.

JavaScript와 Shiny를 함께 사용해 인터랙티브 문서를 만드는 경우, OJS에서 Shiny Reactives 사용하기 문서도 도움이 될 수 있습니다.