Поглавје 5 Повторливи документи / извештаи со писмено програмирање (R + markdown)

Во претходното поглавје, се запознавме со некои од главните методи за обезбедување на нашиот програмски код со цел да биде фунцкионален и на нечиј друг компјутер. Разгледавме ситуација со една скрипта и една табела со резултати, но доколку се запрашаме, сигурно ќе се согласиме дека речиси никогаш не е доволно да се испрати (или објави) само една табела или пресметка. Наспроти, често потребно е да се додаде текстуално објаснување или некаков друг контекст на податоците. Исто така, во многу случаи, нашите визуелизации во форма на табели или графици, или нашите статистички резултати (t-вредности, p-вредности, равенки за регресија), треба да ги прикажеме заедно со програмскиот код кој сме го напишале за да дојдеме то тие резултати.

За едноставно комбинирање на код, податоци, резултати и текст во еден документ, светот на R се користи rmarkdown (Allaire et al. 2020). rmarkdown овозможува комбинирање на сите елементи на едно истражување во документ погоден за понатамошно споделување. Патем, така е напишан и овој прирачник, кој исто така цели да биде повторлив.

5.1 Форматирање на текст со markdown

Markdown, за разлика од markup програмски јазици како HTML или LaTeX има за цел да го поедностави процесот на форматирање на текст. За детална референца на филозофијата и синтаксата на markdown, погледнете ги официјалните вебсајти нa оригиналната спецификација или поновата стандардизирана спецификација. Во контекст на R и Rstudio погледнете го поглавјето за Rmarkdown во книгата R for Data Science или овој блогпост (и линковите таму) посветен на процесот на развивање на R код, или развивање на една анализа низ призмата на писмено програмирање со rmarkdown („писмено“ го преведуваме од англиското ‘literate programming’).

Тука, накратко ќе ги споменеме најчестите компоненти. На пример, обичниот текст со мала декорација прикажан тука:

Оваа _реченица_ е напишана во **markdown** но не е процесирана за да се покаже синтаксата. 
На [овој линк](https://kbroman.org/knitr_knutshell/pages/Rmarkdown.html) или 
[овој линк](https://rmarkdown.rstudio.com/authoring_quick_tour.html) можете да 
прочитате повеќе за пишување `Rmarkdown`. 

За директни калкулации во текстот, користите ja следната синтакса: `р 3.14 * 2`. 
Kаде што првиот елемент на парчето (chunk) укажува како да го процесираме кодот што следи. 
**За `R` користете `r`**. (Во ова не-процесирано парче, не користиме кирилично `р` токму со
цел на тоа да ја покажеме синтакста без да го конвертираме кодот во пресметаната вредност)

За прикажување математичка нотација, користете: $P = r^2 * \pi$

по процесирањето ќе биде конвертиран во следниот параграф:

Оваа реченица е напишана во markdown но не е процесирана за да се покаже синтаксата. На овој линк или овој линк можете да прочитате повеќе за пишување Rmarkdown.

За директни калкулации во текстот, користите ja следната синтакса: 6.28. Kаде што првиот елемент на парчето (chunk) укажува како да го процесираме кодот што следи. За R користете r. (Во ова не-процесирано парче, ние користиме кирилично р токму со цел на тоа да ја покажеме синтакста без да го конвертираме кодот во пресметаната вредност.)

За прикажување математичка нотација, користете: \(P = r^2 * \pi\)

Забележуваме дека е навистина еднотавно да се куца обичен текст кој во HTML, PDF, или MS Word документ ќе биде прикажан како задебелен, курзив, со линкови, итн.

5.2 Плетење на текст, код, и резултати со knitr

Досега видовме како можеме лесно да маркираме обичен текст кој ќе биде процесиран во убаво форматиран документ. Она што ни недостасува е комбинирање (плетење) на ваквиот текстот со програмски код и резултатите од тој код. rmarkdown го прави овој чекор супер едноставен. Се што е неопходно е да додадеме парче код кое почнува со нотацијата ```{r} и завршува со нотацијата ```. Тогаш R и пакетот knitr (Xie 2014, 2015, 2020c) ќе се обидат да го интерпретираат и извршат сиот текст во ова парче како R код или коментари што почнуваат со #. Доколку извршувањето на тој код резултира со табела или график, knitr ќе го прикаже тој елемент веднаш под извршениот код.

Ова е далеку полесно со пример:

Пример за еден едноставен Rmd документ што прикажува текст, код, и резултати

Откако ќе го сплетеме овој документ, добиваме:

HTML документ креиран со плетењето на горниот Rmd код

Ова навистина само ја допира површината на тоа што е можно да се направи со алатките како rmarkdown и knitr. Имајќи во предвид дека крајните документи се HTML, LaTex, или MS Word, голем дел од богатсвото на можности на овие далеку поопширни markup системи ќе ви бидат достапни кога пишувате анализи во rmarkdown. Така да, ако сакате да вклучите лого од вашата организација, посебен фонт, специјално форматирње на маргини, пагинација, итн, сето тоа ќе можете тоа да го направите со стандардни методи достапни во HTML или LaTeX.

5.3 Извештаи со параметри

Она што за нас е посебно корисно и интересно, е користењето на оваа платформа за писмено програмирање за пишување на параметризирани извештаи. Што значи ова? Па доколку имате некоj стандарден сет на анализи кои треба да ги повторите за сите градови во Македонија, можете да го извршите вашиот Rmd извештај со параметар за тоа кој град треба да биде обработен. Во самиот изворен код на извештајот, дефинирате yaml преамбула налик на следната:

---
title: Мој Извештај
output: html_document
params:
  grad: Tetovo
---

Ова креира листа на параметри со името params која е достапна во R средината за време на извршувањето на документот, чијшто елементи може да ги употребите на следниот начин:

params$grad

Доколку имаме некоја функција во нашиот извештај која се извршува пред правење на некој график за одреден град:

library(dplyr)
filtriraj_gradovi <- function(podatoci, potreben_grad) {
  podatoci %>% dplyr::filter(grad == potreben_grad)
}

Тогаш можете параметарот даден во преамбулата да го искористите при повикувањето на фунцкијата, и сите натамошни резултати ќе бидат посветени на градот што сме го пратиле како параметар:

# претходен код и текст
filtriraj_gradovi(podatoci = moi_podatoci, potreben_grad = params$grad)
# натамошен код и текст

За да ги направиме сите извештаи побрзо, во можеме да го повикуваме извршувањето во R конзола:

rmarkdown::render(input = "mojizvestaj.Rmd", params = list("Tetovo"))

Оттука, можеме дури и да напишеме for циклус со кој што ќе ги процесираме сите градови наеднаш и ќе генерираме посебен HTML, PDF или MS Word документ се секој град:

gradovi <- c("Tetovo", "Gostivar", "Debar", "Berovo", "Dojran") # ...
for ( i in gradovi) {
  message("Подготвувам извештај за: ", i)
  rmarkdown::render(input = "pateka/do/mojizvestaj.Rmd", params = list(i))
}

Како оваа стратегија ја подобрува повторливоста на нашите анализи? Доколку немаме извештаи со параметри можеме да замислиме две стратегии. Првата, имаме еден главен izvestaj.Rmd којшто никогаш не го менуваме и правиме копии за секој град, така што набрзо нашата работна средина станува невозможна за менаџирање на долг рок:

izvestaj.Rmd
tetovo-izvestaj.Rmd
debar-izvestaj.Rmd
skopje-izvestaj.Rmd
skopje-izvestaj-juni.Rmd
skopje-izvestaj-juni-specijalen-so-logo.Rmd
kichevo-izvestaj-avgust-2019.Rmd
kicevo-izvestaj-avgust.Rmd

Втората, имаме еден izvestaj.Rmd којшто го менуваме директно и секогаш мора да го отвориме, промениме, и извршиме рачно. Така да кога ќе стигнат новите податоци следниот месец имаме 2-3 часа работа да го промениме градот во функцијата горе триесетина пати.

Дури и да го имате потребното време за вакви активности, очигледно е дека со овие опции е далеку полесно да направите грешка отколку со извештајот со параметри, којшто го пишувате еднаш и можете да го користите секогаш кога ќе ви треба без да го менувате изворниот код. Доколку треба да се измени или подобри извештајот, тоа се прави со промена на само еден документ, не треба да се сетите дека kopje-izvestaj-juni-specijalen-so-logo.Rmd треба да се промени засебно бидејќи има нешто специфично.

5.4 Следни чекори

Околината на rmarkdown и knitr е особено богата со алатки за посебни намени што навистина можат да придонесат кон поголема транспарентност и повторливост на вашите анализи и генерално кон поголема продуктивност во вашата работа. Подолу наведуваме само неколку од овие алатки:

5.5 Резиме

Технички гледано, користењето на писмено програмирање, дали со rmarkdown + knitr или Sweave во R или Jypiter тетратки во Python (или некој од другите подджани јазици), додава зависности на нашиот код, и со самото тоа, до некоја мера оди наспроти идејата за правење што помалку претпоставки за контекстот во кој нашиот код ќе биде користен. Но од друга страна, придобивките од комбинирањето на текст, код, и резултати во истиот документ кој лесно може да биде објавен како веб страница веројатно се доволно големи да додавањето на овие зависности во вашиот повторлив проект е оправдано. Без разлика дали пишувате домашна задача или дисертација, можноста да направите корекции во кодот или текстот и да го извршите вашиот Rmd со една команда е секако далеку по-повторливо отколку да копирате бројки помеѓу два или повеќе различни програми пазејќи да замените на сите неопходни места.

Литература

Allaire, JJ, Yihui Xie, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, Hadley Wickham, Joe Cheng, Winston Chang, and Richard Iannone. 2020. Rmarkdown: Dynamic Documents for R. https://github.com/rstudio/rmarkdown.

Chang, Winston, Joe Cheng, JJ Allaire, Yihui Xie, and Jonathan McPherson. 2020. Shiny: Web Application Framework for R. http://shiny.rstudio.com.

Xie, Yihui. 2014. “Knitr: A Comprehensive Tool for Reproducible Research in R.” In Implementing Reproducible Computational Research, edited by Victoria Stodden, Friedrich Leisch, and Roger D. Peng. Chapman; Hall/CRC. http://www.crcpress.com/product/isbn/9781466561595.

Xie, Yihui. 2015. Dynamic Documents with R and Knitr. 2nd ed. Boca Raton, Florida: Chapman; Hall/CRC. https://yihui.org/knitr/.

Xie, Yihui. 2020c. Knitr: A General-Purpose Package for Dynamic Report Generation in R. https://yihui.org/knitr/.