Chapter 19 Rmarkdown and reporting

19.1 Rmarkdown and Word (office down)

DsPub Project 부분

  보고서나 논문을 쉽고 빠르게 작성하는 것도 중요한 부분입니다. 이때 Rmarkdown에 office, officedown 페키지를 사용하여 워드 파일로 변형하는 것을 실습해 보겠습니다. 처음에는 아래와 같이 title, output 부분을 작성해 줍니다.

---
title: officedown을 이용한 반복작업
output:
  #html_document: default
  officedown::rdocx_document: 
  #reference_docx: template/templet.docx
---

  필요한 페키지들을 설치해 줍니다. 이때 중요한 것은 설치가 제대로 되는지 살펴 보는 것입니다. erro가 난다면 그 원인을 찾아 고쳐주는 것이 중요합니다.

if(!require(tidyverse)) install.packages('tidyverse')
if(!require(readxl)) install.packages('readxl')
#if(!require(purrr)) install.packages('purrr')
if(!require(officedown)) install.packages('officedown')
if(!require(officer)) install.packages('officer')
if(!require(flextable)) install.packages('flextable')
#if(!require(formattable)) install.packages('formattable')

  여기에는 몇가지 원칙에 따라 산업지대를 나열해 본 것입니다. exp0_long.xlsx 자료를 불러옵니다.

mm01 =readxl::read_xlsx('data/exp0_long.xlsx') %>%
  mutate(variable = ifelse(variable =='등수', '관찰우선순위', variable))

  산단이름, 산단코드를 나중에 표 caption에 사용하기 위해서 준비합니다. 그리고 표로 만들 데이터를 준비합니다. 여기서는 main_tab이 표가될 데이터 입니다. 다만 총인구점수, 대기오염점수, 유해인자점수, 환경점수는 합산된 점수 이므로 제외하고, 나중에 합쳐줄 생각입니다.

CodeList = mm01 %>% select(`산단코드`, `산단이름`) %>% unique() %>%
  mutate(`산단이름` = str_replace(`산단이름`, " \n", ""))
main_tab = mm01 %>%
  filter(!variable %in% c('총인구점수', '대기오염점수', '유해인자점수', '환경점수'))

  데이터를 원하는 모양의 표로 만드는 작업은 Data Reshap 부분에서 다루니, 여기서는 우선 코드를 source()라는 명령어로 불러오겠습니다. envdbframe.R은 제가 원한는 데이터 형식으로 바꿔준 함수가 있는 것으로, 다른 자료로 실습하는 경우 원하는 표 모양을 만들면 되겠습니다.

source('source/envdbframe.R')
# load data reshape function of MakeDataFrame

  데이트를 원하는 방법대로 가져오는지 보겠습니다. MakeDataFrame에는 앞서 표 caption에 사용할 부분과, 표 body 부분을 만드는 함수 였습니다. 아래처럼 작동합니다.

CodeList %>% nrow() %>%as.numeric() 를 실행해 보세요. 그러면 몇개의 데이터가 있는지 알 수 있습니다. 100개의 데이터가 있는데, 이를 모두 계산해서 list 로 만들어 줍니다.

DataList = lapply(1: c(CodeList %>% nrow() %>%as.numeric()), 
                  MakeDataFrame)

잘되었는지 확인해 봅니다. 첫번재 list 속의 첫번째 list는 무엇인가요?, 첫번재 list 속의 두번째 list 는 무엇인가요?

DataList[[1]][[1]]
DataList[[1]][[2]]

  중복된 항을 지우고 빈칸으로 만들어 보기 편하게 하겠습니다. 이때는 collapse_row라는 함수를 만들어서 사용할 건데요. 이때 {{ }} 을 보게 됩니다. 이는 문자를 변수로 인식시키기 위해 사용하는 방법입니다. 예전에 quo() - !! quo()를 점도 간단하게 한 것으로 생각하면 됩니다. {{ }} 안에 문자는 data.frame(), tibble()안에 변수(variable)로 인식하게 됩니다. 자동화를 위해서 매우 편한 기능입니다.

collapse_rows <- function(df, variable){
  df %>%
    group_by({{ variable }}) %>%
    mutate(groupRow = 1:n()) %>%
    ungroup() %>%
    mutate({{ variable }} := ifelse(groupRow ==1, as.character({{ variable}}), "")) %>%
    select(-c(groupRow))
}

  자 이제 테이블을 만드는 함수를 작성해 보겠습니다. 다른 것보다 flextable()을 주목하면됩니다. flextable()이란 명령어가 워드로 변환했을 때 표로 만들어주는 기능을 하게 됩니다.

loop_table = function(i){
  DataList[[i]][[2]] %>% tibble()%>%
    collapse_rows(`대분류`) %>%
    collapse_rows(`총점수`) %>%
    collapse_rows(`중분류 항목`) %>%
    collapse_rows(`중분류 점수`) %>%
     flextable() %>%
      autofit() %>% fit_to_width(20) %>%
      fontsize(size = 10)
}

  하나만 만들어 볼까요?

loop_table(1)

잘 되는 것을 확인했으니, 100개의 표를 만들어 보겠습니다. 다만, 표를 한 쪽에 2개씩 만드는 작업을 해보겠습니다. caption이라는 파일로 반복적으로 표의 제목이 생성되게 하였습니다. 그리고, autonum 을 이용해서 자동 숫자 입력이 되게 되었습니다.

tab_num <- run_autonum(seq_id = "표", pre_label = "표-", bkm = "")
for(i in 1:50){
  cat("\n\n\\pagebreak\n")
  caption = paste0(DataList[[i*2 -1]][[1]][,1],"-", DataList[[i*2-1]][[1]][,2], "의 점수 요약")
  flextable_to_rmd(loop_table(i*2 -1) %>%
                     set_caption(caption=caption, autonum = tab_num))
  cat("\n\n\\linebreak\n")
  writeLines("\n")
  cat("\n\n\\linebreak\n")
  caption = paste0(DataList[[i*2 -0]][[1]][,1],"-", DataList[[i*2-1]][[1]][,2], "의 점수 요약")
  flextable_to_rmd(loop_table(i*2 -0)%>%
                     set_caption(caption=caption, autonum = tab_num))
  
}

워드 파일을 열어서 확인해 보면 되겠습니다.

19.2 Rmarkdown and PDF

Rmarkdwon 을 word로 만드는 것과 동일한 흐름입니다. 다만, 기본 설정과 flexttable이 아닌 xtable 을 사용한 것만 다릅니다. 동일한 흐름에서 따라 해보세요

latex 설치하기

pdf를 만들기 위한 파일을 설치해 보겠습니다.

터미널에서 texlive-xetex를 설치해 줍니다.

$ sudo apt-get install texlive-xetex

이후 R에서 tinytex 페키지를 설치해 줍니다.

> install.packages('tinytex')
> tinytex::install_tinytex()
> tinytex::tlmgr_install()
> tinytex::latexmk()

다시 터미널에서

$ sudo apt-get install -y latexmk

를 설치해 주고,

주로 사용할 한글 폰트인 나눔명조를 설치해 봅니다.

wget http://cdn.naver.com/naver/NanumFont/fontfiles/NanumFont_TTF_ALL.zip
wget https://github.com/naver/nanumfont/releases/download/VER2.5/NanumGothicCoding-2.5.zip
unzip NanumFont_TTF_ALL.zip
unzip NanumGothicCoding-2.5.zip

sudo mkdir -p /usr/share/fonts/truetype/nanum-gothic
sudo mv *.ttf /usr/share/fonts/truetype/nanum-gothic

자 이제 rmarkdown 파일을 열고 아래 항목을 따라서 해보겠습니다. 이후 과정은 rmarkdown과 word 부분과 같은 흐름으로 그것을 보고 하시면 되겠습니다.

---
title: "부록 1, 00 00  00 집단에서의 우선순위 점수 요약"
author: ""
date: ""
header-includes:
   - \usepackage{longtable}
   - \usepackage{setspace}\doublespacing
   - \usepackage[labelformat = empty]{caption}

mainfont: NanumMyeongjo
output: 
  pdf_document:
    latex_engine: xelatex
   #html_document
---
library(readxl)
library(tidyverse)
library(htmlTable)
library(kableExtra)
library(knitr)
library(xtable)
library(data.table)
#source('source/header.R')
mm01 =readxl::read_xlsx('data/exp0_long.xlsx') %>%
  mutate(variable = ifelse(variable =='등수', '관찰우선순위', variable))
CodeList = mm01 %>% select(`산단코드`, `산단이름`) %>% unique() %>%
  mutate(`산단이름` = str_replace(`산단이름`, " \n", ""))
main_tab = mm01 %>%
  filter(!variable %in% c('총인구점수', '대기오염점수', '유해인자점수', '환경점수'))
#CodeList[1,][1] %>% as.character()
source('source/envdbframe.R')
gg2 = MakeDataFrame(3)
gg2[[1]]
gg2[[2]]
CodeList %>% nrow()
c(CodeList %>% nrow() %>%as.numeric())
DataList = lapply(1: c(CodeList %>% nrow() %>%as.numeric()), 
                  MakeDataFrame)
DataList[[1]][[1]]
DataList[[1]][[2]]
plotTable = function(i){kbl(DataList[[i]][[2]], "latex", booktabs = T, 
    caption = paste0('표-', i, ". ", DataList[[i]][[1]][,1], 
                     "-", DataList[[i]][[1]][,2], "의 점수 요약")) %>%
    collapse_rows(columns = 1:6, valign = "top") #%>%
    #row_spec(14, extra_latex_after = "\\cline{1-5}")
}
for (i in 1:50){
 cat("\n\n\\pagebreak\n")
 cat(plotTable(i*2-1))
 cat(plotTable(i*2))
 cat("\\clearpage")
}