React를 근간으로 마이크로소프트에서 Fluent UI를 제작하였다. 이를 R Shiny 환경에서 사용할 수 있도록 가져온 것이 shiny.react, shiny.fluent 팩키지다.
오픈 통계 팩키지에 필요한 기본 기능을 shiny.fluent를 통해 구축해보자.
ui.R
# 0. Page, Card 함수 선언 --------------
<- function (title, subtitle, contents) {
makePage tagList(div(
class = "page-title",
span(title, class = "ms-fontSize-32 ms-fontWeight-semibold", style =
"color: #323130"),
span(subtitle, class = "ms-fontSize-14 ms-fontWeight-regular", style =
"color: #605E5C; margin: 14px;")
),
contents)
}
<- function(title, content, size = 12, style = "") {
makeCard div(class = glue("card ms-depth-8 ms-sm{size} ms-xl{size}"),
style = style,
Stack(
tokens = list(childrenGap = 5),
Text(variant = "large", title, block = TRUE),
content
))
}
<- function(...) {
Grid div(
class = "ms-Grid",
dir = "ltr",
style = "padding: 0px",
...
)
}
<- function(..., class = "ms-sm12") {
GridItem div(
class = paste("ms-Grid-col", class),
style = "padding: 10px",
...
)
}
<- function(...) {
plotCard # cat_waffle_card
tagList(div(
class = "page-title",
span("단변량: 범주형 시각화", class = "ms-fontSize-32 ms-fontWeight-semibold", style =
"color: #323130")
),Stack(
horizontal = TRUE,
tokens = list(childrenGap = 50),
plotOutput("ggplotImageId"),
plotOutput("ggplotWaffleId"),
plotOutput("ggplotPieId"),
plotOutput("ggplotBarId")
)
)
}
# 1. 페이지 구축 --------------
## * 데이터셋 ----------
<- makePage(
cat_data_page "단변량 분석",
"범주형 변수: 데이터",
div(
class = "card ms-depth-8 ms-sm4",
style = "overflow: auto",
Stack(
horizontal = TRUE,
tokens = list(childrenGap = 10)
),gt_output("datasetId")
)
)
## * 통계량 ----------
<- makePage(
cat_statistics_page "단변량 분석",
"범주형 변수: 데이터",
div(
class = "card ms-depth-8 ms-sm4",
style = "overflow: auto",
Stack(
horizontal = TRUE,
tokens = list(childrenGap = 10)
),gt_output("statisticsId")
)
)
# 2. 카드 구축 --------------
<- plotCard()
basic_plot_card
## * 막대 그래프 -----
<- makeCard(
cat_barplot_card "막대그래프",
plotOutput("ggplotBarId"),
style = 4
)
## * 원 그래프 -----
<- makeCard(
cat_pieplot_card "원그래프",
plotOutput("ggplotPieId"),
style = 4
)
## * 와플 그래프 -----
<- makeCard(
cat_waffle_card "와플그래프",
plotOutput("ggplotWaffleId"),
style = 4
)
## * 이미지 그래프 -----
<- makeCard(
cat_image_card "이미지 그래프",
plotOutput("ggplotImageId"),
style = 4
)
# Shiny UI --------------
<- fluentPage(
ui
cat_data_page,
cat_statistics_page,
basic_plot_card )
server.R
<- function(input, output) {
server
# 1. show dataset ----
$datasetId <- render_gt(
outputexpr = gender_gt,
height = px(600),
width = px(600)
)
# 2. show descriptive statistics ----
$statisticsId <- render_gt(
outputexpr = gender_stat_gt,
height = px(600),
width = px(600)
)
# 3. show basic ggplot ----
## 3.1. pie chart
$ggplotPieId <- renderPlot(
output
gender_piechart_gg
)## 3.2. bar chart
$ggplotBarId <- renderPlot(
output
gender_barplot_gg
)## 3.3. Waffle chart
$ggplotWaffleId <- renderPlot(
output
gender_waffle_gg
)## 3.4. Image chart
$ggplotImageId <- renderPlot(
output
gender_image_gg
) }
global.R
library(dplyr)
library(ggplot2)
library(glue)
library(leaflet)
library(plotly)
library(sass)
library(shiny)
library(shiny.fluent)
library(shiny.router)
library(statdata)
library(waffle)
library(gt)
library(ggtextures)
# 1. Dataset ----
<- statdata::gender
gender
<- gender %>%
gender_gt ::gt()
gt
# 2. Descriptive Statistics ----
<- gender %>%
gender_stat_gt count(성별, name = "명수") %>%
mutate(성비 = glue::glue("{명수 / sum(명수) * 100} %")) %>%
::gt()
gt
# 3. Visualization -----
<- gender %>%
gender_tbl count(성별, name = "명수")
<- gender_tbl %>%
gender_barplot_gg ggplot(aes(x = 성별, y=명수)) +
geom_col(width = 0.3, fill = "midnightblue") +
scale_y_continuous(limits = c(0,10), labels = scales::number_format(accuracy = 1)) +
labs(x = "성별",
y = "명수",
title = "중학교 성별 범주형 데이터") +
theme_bw(base_family = "NanumGothic")
<- gender_tbl %>%
gender_piechart_gg ggplot(aes(x = "", y=명수, fill = 성별)) +
geom_bar(width = 1, stat = "identity", color = "white") +
coord_polar("y", start = 0) +
geom_text(aes(label = glue::glue("{성별} : {명수}")),
position = position_stack(vjust = 0.5),
family = "NanumGothic",
size = 10) +
theme_void(base_family = "NanumGothic") +
scale_fill_viridis_d() +
theme(legend.position = "bottom") +
labs(title = "중학교 성별 범주형 데이터")
<- gender_tbl %>%
gender_waffle_gg ggplot(aes(fill = 성별, values=명수)) +
geom_waffle(n_rows = 6, size = 0.33, colour = "white") +
scale_fill_manual(name = NULL,
values = c("#BA182A", "#FF8288"),
labels = c("남자", "여자")) +
coord_equal() +
theme_void(base_family = "NanumGothic")
<- gender_tbl %>%
gender_image_gg mutate(image = list(
::image_read_svg("https://raw.githubusercontent.com/tidyverse-korea/pkg_doc/master/fig/man-svgrepo-com.svg"),
magick::image_read_svg("https://raw.githubusercontent.com/tidyverse-korea/pkg_doc/master/fig/woman-svgrepo-com.svg")
magick%>%
)) ggplot(aes(x = 성별, y=명수, image = image)) +
geom_isotype_col() +
scale_fill_manual(name = NULL,
values = c("#BA182A", "#FF8288"),
labels = c("남자", "여자")) +
theme_bw(base_family = "NanumGothic") +
scale_y_continuous(limits = c(0,10), labels = scales::number_format(accuracy = 1))
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com