---
-sections: true
number:
format:
html: true
toc:
execute: false
warning: false
error: auto
freeze---
Day 1: Quarto를 활용한 대시보드 제작
실습 목표
Quarto를 이용하여 데이터 대시보드(dashboard) 만들기
1 Quarto 문서 생성
R studio를 열고 File > New File > Quarto Document를 실행한다. Title과 Author란에 적절한 텍스트를 기입하고 아래에 위치한 Create 버튼을 클릭한다.
그렇다면 아래의 화면이 보일 것이다.
2 Quarto 문서의 구조
Quarto 문서는 두 개의 서로 다른 에디터를 사용하여 편집할 수 있다. Figure 2 에서 왼쪽은 비주얼 에디터(visual editor), 오른쪽은 소스 에디터(source editor)를 사용한 것이다. 소스 에디터는 Notion과 유사한 마크다운 형식을 사용하며, 비주얼 에디터는 마치 워드프로세서를 다루듯 Quarto 문서를 작성할 수 있다.
Quarto 문서는 크게 세 부분으로 나뉘어진다.
YAML 헤더(header)
코드 청크(code chunk)
마크다운 텍스트
2.1 YAML 헤더
YAML 헤더는 Quarto 문서의 최상단에 위치하는 것으로, 문서의 전반적인 사항을 관장한다. YAML 헤더의 모든 요소는 기본적으로 key: value
의 형태를 띤다. key
는 항목이고, value
는 해당 항목에 대한 옵션값이다. Figure 1 에는 title
, format
, editor
의 세 key가 사용되었는데, 제목은 “Hello Quarto”, 산출 포맷은 HTML이며, Quarto 다큐먼트 작성을 비주얼 에디터를 통해 할 것이라는 점을 명시하고 있다.
이 밖에도 다양한 key가 존재하는데, 링크에서 자세한 정보를 확인할 수 있다. 보통 아래의 것들이 중요하다.
key | 설명 |
---|---|
title | 다큐먼트의 제목 |
date | 다큐먼트 작성 날짜 |
author | 다큐먼트 저자 이름 |
format | 다양한 포맷 관련 사항의 지정 |
toc | 목차 삽입 |
number-section | 섹션 제목에 자동 번호 부여 여부 |
execute: echo | 소스 코드의 포함 여부를 글로벌하게 설정, 보통 true |
execute: warning | 경고 메시지를 산출물에 나타나게 할지를 글로벌하게 설정, 보통 false |
editor | 비주얼 에디터와 소스 에디터 중 선택, 보통 visual |
---
으로 둘러싸인 YAML에 아래와 같은 몇 가지 key: value
를 더해보자.
2.2 코드 청크
프로그래밍 언어의 코드가 들어가는 부분이다. R을 사용하는 경우 {r}
로 시작한다. 뒤이어 배울 데이터 불러오기, 정리하기, 변형하기, 시각화하기, 탐색하기, 수집하기와 관련된 모든 종류의 코드가 여기에 들어갈 수 있다. 보통 하나의 Quarto 문서 내에 다수의 코드 청크가 포함된다. 각 코드 청크 내에서 코드를 실행할 수 있는데, 한 단위씩 실행할 때는 ctrl(또는 Cmd) + enter, 한 코드 청크 내 모든 코드를 실행하고자 할 때는 ctrl(또는 Cmd) + shift + enter 단축키를 사용한다.
각 코드 청크 앞 부분에 해당 코드 청크와 관련된 다양한 옵션을 #|
형태로 삽입할 수 있는데, YAML 헤더에서처럼 key: value
의 형태를 띤다. 아래의 옵션들은 코드 청크의 내용이나 실행 결과, 오류 메시지 등이 최종 산출물에 어떻게 표현되는지 결정하는 것들이다. 이 밖에도 다양한 옵션들이 존재하는데, 구글링 혹은 Quarto 공식 가이드를 참고하자.
Option | Run code | Show code | Output | Plots | Messages | Warnings |
---|---|---|---|---|---|---|
eval: false |
X | X | X | X | X | |
include: false |
X | X | X | X | X | |
echo: false |
X | |||||
results: hide |
X | |||||
fig-show: hide |
X | |||||
message: false |
X | |||||
warning: false |
X |
2.3 마크다운 텍스트
Quarto는 기본적으로 마크다운 텍스트 작성을 기반으로 하고 있다. 마크다운 텍스트 작성에 앞서 언급한 비주얼 에디터는 큰 역할을 하는데, 이는 마크다운 언어의 사용자 편의성을 한번 더 강화한 것으로 볼 수 있다.
기본적인 Quarto 작성법은 다음과 같다.
텍스트: 그냥 작성
코드 청크(Code Chunk): Insert > Executable Cell > R(Ctrl+Alt+I)
표(Table): Insert > Table
그림(Figure): Insert > Figure
링크(Link): (원하는 텍스트 선택 후) Insert > Link
머릿말(Header): Normal > Header 1~6 중 선택
2.4 Quarto 문서 작성 팁
추가로 몇 가지의 팁을 소개한다.
첫째, R의 패키지나 함수를 다르게 표시할 수 있다. 지금까지의 실습록에서 tidyverse 함수를 tidyverse
와 같이 표시하던 것이 기억날 것이다. 이는 해당 텍스트를 선택한 후, Format에서 Code를 누르면 생성된다. 혹은 Ctrl+D로 실행할 수 있다.
둘째, Call-out
이다. 문서 중간에 팁이나 주의를 알려주고 있다.
Callout은 문서 중간에 팁이나 주의를 알려주는데 사용할 수 있다.
Callout에는 공지(note), 팁(tip), 중요사항(important), 주의(caution), 경고(warning) 등이 있다. 이는 비주얼 에디터 메뉴 Insert-Callout에서 선택할 수 있고, :::
으로 둘러싸인 부분에 글이나 코드 청크를 작성하면 된다. 다양한 Callout의 옵션은 공식 가이드에서 찾아볼 수 있다.
2.5 Quarto 문서 작성
위에서 배운 내용을 기반으로 간단한 Quarto 문서를 작성해본다.
3 대시보드의 기본 구조
대시보드는 기본적으로 다섯 가지의 구성요소로 이루어진다. 각각은 메인 바디, 헤더, 내비게이터, 사이드바, 푸터이다.
첫째, 메인 바디(main body)는 대시보드의 핵심 요소이다. 메인 바디는 카드(card)라고 불리는 기본 단위들로 구성된다. 개별 카드는 다양한 내용 요소(텍스트, 그래프, 표, 지도, 밸류박스 등)를 가질 수 있다. 즉, 어떤 카드 속에는 그래프가 들어가며, 어떤 카드 속에는 지도가 들어간다. 이러한 카드들은 특정한 레이아웃 요소(페이지, 행, 열, 탭셋 등)를 통해 메인 바디에 배열된다. 페이지(page)는 대시보드 레이아웃 요소 중 최상위 레벨인데, 개별 페이지는 다수의 행(row) 혹은 열(column)로 구성된다. 행 혹은 열을 또다른 행 혹은 열이 아닌 탭 클릭 방식으로 분할하고 싶을 때 탭셋(tabset)이 사용된다.
둘째, 헤더(header)는 대시보드의 가장 중요한 메타 정보(로고, 제목, 저자 등)를 포함한다.
셋째, 내비게이터(navigator)는 최상위 레이아웃인 페이지간 이동을 통제한다.
넷째, 사이드바(sidebar)는 주로 사용자의 인풋(input)을 받을 때 사용되는 것으로, 동적인 대시보드에서 주로 사용된다. Quarto는 사이드바 외에 툴바(toolbar)와 카드인풋(card input)과 같은 옵션을 제공한다.
다섯째, 푸터(footer)는 헤더와 유사한 기능을 하는데, 주로 부차적인 매타 정도를 포함한다.
다섯개의 구성 요소 중 가장 중요한 것은 메인 바디, 해더, 내비게이터이다. Quarto는 헤더와 내비게이터를 통합한 내비게이션바(navigation bar)를 제공한다. 사이드바는 Shiny
페키지를 활용한 동적인 대시보드에서는 매우 중요하지만, 이번 실습에서는 사용하지 않는다. 푸터는 가장 지엽적인 요소이다.
다음의 대시보드를 살펴보자.
이 대시보드는 크게 내비게이션바와 메인 바디로 구성되어 있다. 네비게이션바에는 다음의 내용이 포함되어 있다.
이 대시보드의 제목(title)은 ’고객이탈(Customer Chrun)’이고 회사 이름은 DEMOCO(로고)이다.
이 대시보드는 모두 두 개의 페이지(page)로 구성되어 있다. 페이지의 이름은 각각 ’Churn (Standard)’과 ’Data’이다.
메인 바디는 다음과 같은 레이아웃 요소들로 구성되어 있다.
첫 번째 페이지(Churn (Standard))는 세 개의 행(row)으로 구성되어 있다.
첫 번째 페이지의 첫 번째 행은 세 개의 카드(card)로 구성되어 있는데, 내용 요소는 모두 밸류박스(value box)이다.
첫 번째 페이지의 두 번째 행은 두 개의 열(즉, 카드)로 구성되어 있는데, 내용 요소는 모두 그래프(graph)이다.
첫 번째 페이지의 세 번째 행은 단일한 열(즉, 카드)로 구성되어 있는데, 내용 요소는 테이블(table)이다.
두 번째 페이지에도 다양한 사항이 포함되어 있을 것이다.
이 밖에도 다양한 대시보드의 예시를 Quarto 갤러리에서 찾아볼 수 있다.
4 레이아웃 설정법
4.1 페이지의 설정
페이지(page)는 최상위 레이아웃 요소이다. 기본 원칙은 다음과 같다.
헤더 1(header 1) 레벨이 페이지의 구분을 결정한다.
Quarto에서는 페이지가 내비게이션바에 나타난다.
# Page A
# Page B
4.2 내비게이션 바의 설정
내비게이션바는 헤더와 내비게이터로 구성된다. 내비게이터는 페이지가 설정된 경우에만 나타나게 된다. 헤더는 다른 Quarto 문서와 마찬가지로 YAML 헤더를 통해 통제된다.
제목(title): 대시보드 전체의 이름을 결정한다.
저자(author): 만든 사람이나 관리 회사의 이름이지만, 부제로 활용되기도 한다.
-
포맷(format): 기본 설정인 대시보드(dashboard) 하에 다양한 하위 설정이 가능하다.
logo: 로고 그림 파일을 지정하면 내비게이션바의 왼쪽 끝에 나타난다.
nav-buttons: github이나 이메일 연결을 설정할 수 있다.
scrolling: true 설정: 디폴트는 false인데, 레이아웃 요소들의 높이들의 합이 100%가 되도록 일괄적으로 조절된다. true로 지정하면, 개별 내용 요소의 원 크기를 그대로 살리면서 스크롤되게 디자인이 바뀐다. 둘 다를 실험해 보고 자신의 목적에 맞는 것을 고른다.
테마(theme): 대시보드의 외관을 한꺼번에 바꿀 수 있다. 모두 25개의 부트스와치(bootswatch) 테마가 존재한다. 여러가지를 실험해 보고 자신의 취향에 맞는 것을 선정한다.
자세한 사항은 아래의 예시 대시보드 만들기에서 확인한다.
4.3 사이드바의 설정
사이드바(sidebar)는 {.sidebar}
태그를 통해 만들 수 있는데, 헤더 1(header 1) 레벨이므로 특정한 페이지에 종속되지 않는다. 사이드바는 주로 사용자의 투입을 받을 때 사용되기 때문에 동적인 대시보드에 주로 사용된다. 정적인 대시보드의 경우에는 텍스트를 통한 특정 정보의 제공에 사용될 수 있다.
# {.sidebar}
Sidebar content
4.4 행과 열의 설정
행(row)과 열(column)은 가장 기본이 되는 레이아웃 요소이다. 기본 원칙은 다음과 같다.
헤더 2(header 2) 레벨이 행과 열의 구분을 일차적으로 결정한다.
헤더 3(header 3) 레벨이 하위 행과 열의 구분을 이차적으로 결정한다.
Row와 Column 옆에
{height}
,{width}
태그를 통해 가로 세로의 상대적인 크기를 정한다.
## Row {height=70%}
1
Card
## Row {height=30%}
### Column {width=40%}
2-1
Card
### Column {width=60%}
2-2
Card
# Page B
3 Card
4.5 탭셋의 설정
Row나 Column에 {.tabset}을 표기하면, 하위의 행과 열이 탭으로 구분된다. 이렇게 하면 카드의 크기가 지나치게 줄어드는 단점을 해소할 수 있다.
4.6 기본 구조 살펴보기
위를 바탕으로 대시보드의 골격을 작성해본다.
---
: "dashboard"
title: dashboard
format: default
theme: visual
editor:
editor_options: console
chunk_output_type---
# {.sidebar}
Sidebar content
# Page A
## Row {height=70%}
1
Card
## Row {height=30%}
### Column {width=80%} {.tabset}
#### Tab1
2-1
Card
#### Tab2
2-2
Card
### Column {width=20%}
2-3
Card
# Page B
3 Card
위와 같이 설정하면 다음과 같은 결과를 얻을 수 있다.
5 카드와 내용 요소
카드(card)란 특정한 내용 요소(텍스트, 벨류박스, 테이블, 그래프, 지도 등)를 포함하고 있는, 대시보드의 가장 기본적인 단위이다. 다음의 두 가지 사항이 중요하다.
카드의 제목이 중요하다. 완성된 대시보드 상에 등장하기 때문에 사용자가 이해하기 쉬운 제목이 부여되어야 한다.
내용 요소에 따라 카드를 작성하는 방법이 조금 다르다.
내용 요소 제작의 세세한 사항은 아래의 “예시 대시보드 만들기”에서 확인한다.
5.1 그래프
Quarto는 그래프 하나를 만들어내는 코드 청크를 하나의 카드로 인식한다. 그래프 카드의 제목은 코드 청크 내의 #| title:
옵션을 통해 부여된다. ggplot2
와 같은 정적인 플롯 도구 뿐만 아니라 plotly
와 같은 반응형 플롯 도구를 사용하여 그래프 카드를 생성한다.
5.2 테이블
Quarto는 테이블 하나를 디스플레이하는 코드 청크를 하나의 카드로 인식한다. 테이블 카드의 제목은 코드 청크 내의 #| title:
옵션을 통해 부여된다. knitr
패키지의 kable()
함수, DT
패키지의 datatable()
함수 등을 이용해 테이블 카드를 생성한다.
5.3 지도
Quarto는 지도 하나를 디스플레이하는 코드 청크를 하나의 카드로 인식한다. 지도 카드의 제목은 코드 청크 내의 #| title:
옵션을 통해 부여된다. ggplot2
와 같은 정적인 지도 제작 도구 뿐만 아니라 leaflet
과 같은 반응형 지도 제작 도구를 사용하여 지도 카드를 생성한다.
5.4 텍스트
일종의 텍스트 박스도 하나의 카드로 간주된다. 그래프, 테이블, 지도가 하나의 코드 청크가 하나의 카드로 인식되는데 반해 텍스트 카드는 다른 형식을 취한다. ::: {.card}
div를 사용해야 하며 괄호 내부에 title=
옵션을 사용해 제목을 지정해야 한다. 가령 {.card title="Text"}
와 같이 표기해야 한다.
5.5 밸류박스
요약적 수치를 큰 박스 속에 나타내는 것을 밸류박스(value box)라고 하는데, 코드 청크로 표현하지만 형식은 조금 다르다. #| content: valuebox
라는 옵션이 반드시 포함되야 하며, 제목을 지정하기 위해 #| title:
옵션도 필요하다. 또한 리스트를 이용해 아이콘(icon), 컬러(color), 수치(value)를 지정해야 한다.
아이콘은 부트스트랩 아이콘(bootstrap icon)이 사용된다. 적절한 아이콘을 찾고 그 이름을 #| title:
옵션을 통해 설정하는 것이 중요하다.
모든 컬러가 다 사용가능한 것은 아니다. 아래의 표를 참조하여 컬러를 설정해야 한다.
Color Alias | Default Theme Color(s) |
---|---|
primary |
Blue |
secondary |
Gray |
success |
Green |
info |
Bright Blue |
warning |
Yellow/Orange |
danger |
Red |
light |
Light Gray |
dark |
Black |
6 예시 대시보드 만들기
위의 사항을 바탕으로 예시 대시보드(https://sechangkim.quarto.pub/my-first-dashboard/)에 접속하여 구성을 살펴본다. 다음의 사항에 주목한다.
내비게이션바에 서울대학교 로고가 있고, 오른쪽 맨 끝애 홈페이지 및 이메일 아이콘이 위치해 있다.
대시보드가 네 개의 페이지(Intro, Graphs, Tables, Maps)로 나뉘어져 있고, 각 페이지마다 행, 열, 탭셋과 같은 레이아웃 요소들이 배치되어 있다.
어떤 식으로 제작할 수 있을지 생각해 본다. 새로운 프로젝트를 생성하고 Quarto 다큐먼트를 생성한다. 아래는 해당 대시보드를 만들기 위해 사용된 코드이다. 참고하여 자신만의 대시보드를 만들어 본다. 단, 로고 및 홈페이지 주소는 반드시 자신의 것으로 수정해야 한다.
6.1 YAML 해더
특히, nav-buttons:
옵션의 지정 형식에 주의한다. scrolling
옵션과 다양한 theme:
옵션을 시험해 본다.
---
: "My First Dashboard"
title: Your name
author:
format:
dashboard-resources: true
embed: img/snu_ui_download.png
logo-buttons:
nav- icon: house-door-fill
: Your Blog Address
href-label: GitHub
aria- icon: envelope
: mailto:vs5345@snu.ac.kr
href-label: Mail
aria# scrolling: true
: default
theme: visual
editor:
editor_options: console
chunk_output_type---
6.2 Intro 페이지
Intro라는 이름의 페이지를 설정한다.
# Intro
6.2.1 첫번째 행: Text 카드
행을 설정하고 행의 상대적인 높이(10%)를 지정한다.
## Row {height="12%"}
텍스트 카드를 생성한다. 텍스트 카드를 생성하기 위해 {.card}
태그가 사용되어야 하며, 텍스트 카드의 제목을 지정하기 위해 title=
옵션이 사용되어야 함에 주의한다.
::: {.card title="Text"}
This is my first dashboard.:::
6.2.2 두번째 행의 탭셋: Histogram of GDP per capita & Table of Mean Values
행을 설정하고 행의 상대적인 높이(70%)를 지정한다. 탭셋을 생성하기 위해 {.tabset}
태그가 사용되어야 함에 주의한다.
## Row {.tabset height="70%"}
그래프 카드를 생성하기 위해 ggplot2
패키지를 활용한다. 그래프 카드의 제목을 지정하기 위해 title=
옵션이 사용되어야 함에 주의한다. 두 개의 그래프를 지난 실습에서 배웠던 patchwork
함수로 가로 배치하였다. 이때 산출될 플롯의 크기는 fig-width
와 fig-height
로 조정할 수 있다.
#| title: "Histogram of GDP per capita"
#| fig-width: 20
#| fig-height: 6
library(tidyverse)
library(gapminder)
library(patchwork)
p1 <- gapminder |>
filter(year==2007) |>
ggplot(aes(x=gdpPercap))+
geom_histogram()
p2 <- gapminder |>
filter(year==2007) |>
ggplot(aes(x=gdpPercap, y=lifeExp))+
geom_point()
p1|p2
테이블 카드를 생성하기 위해 knitr
패키지의 kable()
함수를 활용한다. 테이블 카드의 제목을 지정하기 위해 title=
옵션이 사용되어야 함에 주의한다.
6.2.3 세번째 행의 3개의 밸류박스
행을 설정하고 행의 상대적인 높이(18%)를 지정한다.
## Row {height="18%"}
첫번째 밸류박스를 생성한다. #| content: valuebox
옵션과 #| title:
옵션이 사용됨에 주의한다.
#| content: valuebox
#| title: "Number of Countries"
n_countries <- gapminder |> distinct(country) |> nrow()
list(
icon = "asterisk",
color = "primary",
value = n_countries
)
두번째 밸류박스를 생성한다.
#| content: valuebox
#| title: "First Year"
<- gapminder |> distinct(year) |> pull() |> first()
first_year list(
icon = "airplane",
color = "secondary",
value = first_year
세번째 밸류박스를 생성한다.
#| content: valuebox
#| title: "Last Year"
last_year <- gapminder |> distinct(year) |> pull() |> last()
list(
icon = "bank",
color = "success",
value = last_year
)
더 다양한 아이콘이 궁금하다면 이 웹사이트를 참고할 것.
6.3 Graphs 페이지
Graphs라는 이름의 페이지를 설정한다.
# Graphs
6.3.1 첫번째 행의 그래프 카드: GDP and Life Expectancy
행을 설정한다.
## Row
ggplot2
패키지를 활용하여 그래프 카드를 생성한다.
#| title: GDP and Life Expectancy
gapminder |>
filter(year == 2007) |>
ggplot(aes(x = log10(gdpPercap), y = lifeExp)) +
geom_point(aes(color = continent), show.legend = FALSE) +
geom_smooth() +
facet_wrap(~continent, ncol = 5)
6.3.2 두번째 행의 그래프 카드: Population & Life Expectancy
첫번째 그래프(Population)를 위한 열을 설정한다.
### Column
그래프 카드를 생성한다.
#| title: Population
gapminder |>
summarize(
sum_pop = sum(pop),
.by = c(year, continent)
) |>
ggplot(aes(x = year, y = sum_pop)) +
geom_area(aes(fill = continent)) +
labs(x = "Year", y = "Population", fill = "Continents")
두번째 그래프(Life Expectancy)를 위한 열을 설정한다.
### Column
그래프 카드를 생성한다.
6.4 Tables 페이지
Tables라는 이름의 페이지를 설정한다.
# Tables
단일 행을 설정한다.
## Row
DT
패키지를 활용하여 테이블 카드를 생성한다.
6.5 Maps 페이지
Maps라는 이름의 페이지를 설정한다.
# Maps
단일 행을 설정한다.
## Row
leaflet
패키지를 활용하여 지도 카드를 생성한다.
6.6 대시보드 웹 상에 출판하기
블로그와 마찬가지로 다음의 절차에 따라 완성된 대시보드를 웹 상에 출판한다. 여기서는 Posit에서 제공하는 무료 출판 사이트인 Quarto Pub을 활용한다.
Quarto Pub에 접속하여 계정을 만든다.
RStudio에서, 왼쪽 하단부의 Terminal 탭을 누른다.
프롬프트에 다음과 같이 입력하고 실행한다: quarto publish quarto-pub
6.7 웹사이트 임베딩
대시보드의 컨텐츠를 직접 제작하는 방법도 있지만, 대시보드에 보다 쉽게 동적, 반응형 시각화를 실현하는 방법은 이미 동적, 반응형 시각화가 구현되어 있는 웹사이트를 대시보드에 불러오는 것이다. 이것을 임베딩(embedding)이라고 하는데, HTML의 iframe
태그를 사용한다.
통계청의 통계놀이터(https://kosis.kr/edu/)는 다양한 주제에 대해 동적, 반응형 시각화를 제작하여 이용자들에게 제공하고 있다. 해당 홈페이지의 [비주얼 통계]에서 “우리나라 출생아 수와 합계 출산율 변화”를 검색하면 동적, 반응형 시각화가 구현된 웹페이지(https://kosis.kr/edu/visualStats/detail.do)를 볼 수 있다. 아래와 같은 코드를 Quarto에 삽입하면 해당 웹페이지를 임베딩할 수 있다. src=""
부분만 교체하면 대부분의 웹사이트를 임베딩할 수 있다. 단, 광고가 많이 붙어 있는 웹사이트는 잘 안된다. style=""
부분을 적절히 수정하면 임베딩된 웹사이트의 외견을 바꿔볼 수 있다.
<iframe src="https://kosis.kr/edu/share.do?shareID=S0500_16"
loading="lazy" style="width: 100%; height: 600px; border:
0px none;" allow="web-share; clipboard-write"></iframe>
Our World in Data(https://ourworldindata.org/)는 아름다운 동적, 반응형 시각화 자료를 제공하는 것으로 유명하다. 심지어 공유 버튼을 눌렀을 때 </> Embed
라는 옵션이 나타나는데, 이것을 누르면 위와 같은 iframe 태그 내용이 그대로 나타나기 때문에 복사하여 붙이기만 하면 된다. Chart
탭 뿐만 아니라 Table
탭과 Map
탭도 있으니 눌러서 내용을 확인할 수 있다.
<iframe src="https://ourworldindata.org/grapher/child-mortality?time=earliest..latest&tab=chart"
loading="lazy" style="width: 100%; height: 600px; border: 0px none;" allow="web-share; clipboard-write"></iframe>