-
Notifications
You must be signed in to change notification settings - Fork 1
/
booklet.tex
1394 lines (1083 loc) · 162 KB
/
booklet.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode}{hyperref}
\PassOptionsToPackage{hyphens}{url}
%
\documentclass[
]{book}
\usepackage{lmodern}
\usepackage{amsmath}
\usepackage{ifxetex,ifluatex}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\usepackage{amssymb}
\else % if luatex or xetex
\usepackage{unicode-math}
\defaultfontfeatures{Scale=MatchLowercase}
\defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\fi
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
\usepackage[]{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
\KOMAoptions{parskip=half}}
\makeatother
\usepackage{xcolor}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
pdftitle={Препораки за повторливо анализирање на податоци},
pdfauthor={Теофил Наков, Новица Наков, Слободен софтвер Македонија},
hidelinks,
pdfcreator={LaTeX via pandoc}}
\urlstyle{same} % disable monospaced font for URLs
\usepackage{color}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\usepackage{framed}
\definecolor{shadecolor}{RGB}{248,248,248}
\newenvironment{Shaded}{\begin{snugshade}}{\end{snugshade}}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{0.94,0.16,0.16}{#1}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.77,0.63,0.00}{#1}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\BuiltInTok}[1]{#1}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{#1}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{0.64,0.00,0.00}{\textbf{#1}}}
\newcommand{\ExtensionTok}[1]{#1}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\ImportTok}[1]{#1}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\NormalTok}[1]{#1}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.81,0.36,0.00}{\textbf{#1}}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{#1}}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\RegionMarkerTok}[1]{#1}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\usepackage{longtable,booktabs}
\usepackage{calc} % for calculating minipage widths
% Correct order of tables after \paragraph or \subparagraph
\usepackage{etoolbox}
\makeatletter
\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
\makeatother
% Allow footnotes in longtable head/foot
\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
\makesavenoteenv{longtable}
\usepackage{graphicx}
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
% Set default figure placement to htbp
\makeatletter
\def\fps@figure{htbp}
\makeatother
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{5}
\usepackage{booktabs}
\ifluatex
\usepackage{selnolig} % disable illegal ligatures
\fi
\usepackage[]{natbib}
\bibliographystyle{apalike}
\title{Препораки за повторливо анализирање на податоци}
\author{Теофил Наков, Новица Наков, Слободен софтвер Македонија}
\date{2020-12-18}
\begin{document}
\maketitle
{
\setcounter{tocdepth}{1}
\tableofcontents
}
\hypertarget{ux440ux435ux437ux438ux43cux435}{%
\chapter*{Резиме}\label{ux440ux435ux437ux438ux43cux435}}
\addcontentsline{toc}{chapter}{Резиме}
Волуменот на податоци достапни за најразлични потреби и од најразлични извори расте континуирано. Обработката и објавувето на резултати и податоци, дали од Интернет сообраќајот на вашиот вебсајт, од финансиските трансакции на вашата фирма, од анкети за политички мислења, или од лабораториски експерименти, станува се побрзо и полесно. Исто како и користењето на податоци собрани од Интернет за бизнис одлуки во рамките на вашата фирма. Заедничка за оваа транзиција кон наука за податоци, лична медицина, или бизнис интелегенција, е потребата за транспарентност, отвореност, и повторливост на анализите и резултатите од кои зависиме се повеќе и повеќе. Дали интерно, во нашата фирма за бизнис интелегенција, или јавно за нашите научни истражувања или епидемиолошки предвидувања, доверливи и безбедни процедури за анализа на податоци никогаш не биле толку значајни.
Во овој прирачник се осврнуваме токму на овие таканаречени „најдобри`` пракси за безбедно, стабилно, и \emph{повторливо} работење со податоци. Ќе зборуваме за проблемите што се јавуваат поради не-повторливост, за главните индикатори за не-повторливи проекти, како и за принципите и праксите кои ни овозможуваат да ги надминеме овие проблеми. Низ текстот се обидуваме да дадеме кратки примери, дали вербални или со код, кои ги илустрираат главните препораки и посочуваат кон адекватни софтверски решенија. Се држиме до програмскиот јазик \texttt{R}, којшто е од примарна значајност во светот на анализа на податоци и машинско учење, има активна заедница посветена токму на проблемот на повторливи анализи, и голем број на алатки (библиотеки) наменети кон олеснување на проблемот на повторливост.
Нашата главна препорака е: без разлика на програмскиот јазик кој го користите, или стратегијата за организирање на проекти што најмногу ви прилега, бидете трпеливи, дисциплинирани, и доследни кон почитувањето на препораките за повторливост. Оваа инвестиција ќе ви се исплати на краток и долг рок во форма на заштедено време и ресурси, унапредување, или соработка.
\hypertarget{intro}{%
\chapter{Вовед}\label{intro}}
Во овој текст правиме краток преглед и даваме основни препораки за безбедна пракса при ракување, анализирање, и објавување на податоци. Под „безбедна пракса`` подразбираме чекори коишто доколку ги следиме ќе имаме некаква сигурност дека нашата анализа ќе може да биде повторена во друг контекст (друг компјутер, друга организација, после една година, итн) давајќи ги истите резултати. За оваа цел, потребни е да размислуваме за тоа како наједноставно и најбезбедно да ги споделиме нашите податоци, процедури, и програмски код \emph{заедно} со самите резултати. Инаку, нема никаква надеж дека нашите резултати ќе можат да се повторат.
Се чини дека оваа поента е доволно очигледна и некој би рекол дека воопшто нема потреба да се зборува за ова. Сите се согласуваме со тоа дека кога некоја наша колешка ќе направи некаква анализа, ние, доколку имаме доволно информации за нејзината анализа, можеме да ја повториме и да ги добиеме \emph{истите} резултати. Но во пракса оваа удобна идеја ретко кога се остварува \citep{minocher2020}. Наместо повторливост, кога се обидуваме да повториме некоја анализа вообичаено е да се соочиме со забуна и фрустрација. Ова често завршува со откажување или правење на анализата од почеток, односно, бесполезно и контрапродуктивно губење на време, ресурси и пари. За брз вовед во овие проблеми и значајноста на повторливоста во истражувањето, ви го препорачуваме \href{https://www.youtube.com/watch?v=zwRdO9_GGhY\&t=14s}{ова видео} од \href{https://xcelab.net/rm/}{Ричард МкЕлреат}.
Горната дефиниција на „безбедна пракса`` (без преправање дека ова е некаква прецизна дефиниција) повикува барем две дополнителни поенти за тоа што подразбира да анализираме податоци и да објавуваме резултати на начин што овозможува точно повторување. Имено, објавувањето на резултат мора да биде поддржано со објавување на 1) точните податоци коишто биле употребени да се направи анализата, и 2) деталната процедура којашто била извршена за да се добие резултатот. Подоцна ќе видиме зошто се неопходни овие компоненти (иако веруваме дека е горе-доле очигледно) и на кој начин е најдобро да се презентираат/објават.
Тука е можеби полезно да направиме разлика помеѓу повторливоста која ја опишуваме до сега и еден друг тип на повторливост што има нешто поголема фундаменталност и тежина. Во природните науки, кога зборуваме дека нешто е научна вистина или научно знаење, тоа скоро секогаш се однесува на резултати коишто се повторливи и коишто можат да се докажат од различни агли. Дали почнувајќи со различни податоци, или со поставување на нови експерименти, или со употреба на поинакви анализи, критично е да дојдеме до истиот резултат за тој да биде прифатен како една компонента од тоа како светот функционира (научна вистина). На пример, дека Земјата е сферична може да се докаже со податоци од циркумнавигација, со мерење на аголот на сончевите зраци на различни географски локации, со движењето на Фуковото нишало, со самото постоење на ГПС навигација, со фотографии од возила во орбитата, и така натаму. Значи истиот резултат можеме да го изведеме од многу различни податоци и методи. За разлика од ваквата репликација, фокусот на овој текст е поскромен, и се однесува на далеку полесниот концепт на повторување на истиот рецепт, со истите состојки, за да ја направиме истата пита.
\hypertarget{analogy}{%
\section{Аналогија}\label{analogy}}
Проширување на горната аналогија е добар начин да се запознаеме со главните компоненти на повторливата обработка на податоци. Кога правиме пита, имаме состојки (брашно, квасец, спанаќ, сирење), рецепт од неколку чекори (нарасни го квасецот, замеси тесто, засукај кори), и неопходни алатки (лонче, тарун, тепсија, фурна). Кога сакаме да ја направиме истата пита што ја прави бабата на нашиот пријател, треба да ги имаме сите состојки, информации за сите чекори за подготовка како и сите алатки. Ако имаме брашно, вода и сол ама сме заборавиле квасец, нема да може да замесиме тесто. Ако немаме сукало, ќе треба да тегнеме кори, што секако ќе значи поинаква пита. Значи, за да ја повториме питата потребно е да ги имаме сите неопходни елементи и инфмормации коишто ќе овозможат точно повторување на секој чекор. Затоа не е чудно што рецепти за готвење често доаѓаат со слики или видео. Тоа се медиуми побогати со информации и затоа поадекватни за пренесување комплексни процеси како правење пита. Без разлика од тоа колку детално некој опишал како се сука кора со радиус од 25 cm, со видео од процесот ние добиваме далеку подобро разбирање за процедурата.
Во сферата на анализа за податоци, аналозите на горните компоненти се:
\begin{itemize}
\tightlist
\item
податоците \textasciitilde{} состојки\\
\item
изворниот код \textasciitilde{} рецепт и\\
\item
софтверски пакети од коишто зависи нашиот код \textasciitilde{} алатки
\end{itemize}
На пример, ако правиме анализа на невработеност низ Северна Македонија и имаме една табела со невработеност по општини но сме ги групирале податоците по градови користејќи друга табела, тогаш за точна репликација на нашата анализа треба да ги споделиме двете табели (и брашното и квасецот). Слично, за некој да ги направи истите графици за невработеност по град, треба да го споделиме и нашиот код за правење на анализата (рецептот), како и информации за софтверот во којшто сме го извршиле тој програмски код (тарунот). Некогаш тарунот не е неопходен за да се направи истата пита, можеби само температурата на фурната е битна, и во ваквите случаи можеме да го споделиме рецептот без рестрикција за алатката што треба да се користи. Но во други случаи, дури и да се достапни точните податоци и документираниот изворен код, анализата не може да се повтори без некоја специјална алатка. Во овие случаи ние би требало да ги спакуваме и споделиме дури и нашите алатки.
За среќа, аналогијата помеѓу правење пита и повторување на некоја анализа завршува со споделување на податоците, кодот, и информации за алатките. Имајќи пристап до овие компоненти, дури и никогаш да не сте правеле некаква специфична анализа во некој специфичен софтвер, вие сепак ќе можете да ги извршите истите документирани чекори и да дојдете до истиот резултат. Повторувањето на анализата не бара пракса, умешност, искуство и не зависи од тоа колку е влажно брашното. Ако креирањето повторливи документи или анализи ви звучеше како комплициран концепт, се надеваме дека со оваа аналогија станува јасно дека е далеку полесно од обидот да се направи пита како како бабата на пријателот или пица како од ресторан.
\hypertarget{audience}{%
\section{За кого е наменет овој прирачник}\label{audience}}
Краткиот одговор е: На секој што работи во сферата на истражување, статистика, наука за податоци, за секој што е студент во овие струки, и за секој што е претпоставен на луѓе кои работат во овие и слични струки. Со други зборови, доколку работите со податоци, и некогаш сте се нашле во ситуација кога некој колега, претпоставен, ментор, соработник, донор, рецензент, едитор, новинар, политичар, итн, ве прашал за тоа како може да се повторат или потврдат вашите резултати, тогаш веројатно има нешто во овој прирачник што би ви било од корист. Да разгледаме некои примери.
Пример 1: Работите во невладина организација чијшто фунцкионирање зависи од надворешни грантови, како од македонски така и од странски извори. Се почесто, донорите поставуаат услови за активностите кои тие ги подджуваат, дека сите податоци кои вашата организација ги собира (преку анкети, истражувања, и контакти) како и сите анализи на тие податоци треба да се транспарентни и повторливи. Што во пракса значи дека со завршниот извештај за проектот во кој ги презентирате резултатите, вие ќе треба исто така да покажете јавна депозиција на податоците и изворниот код користен да се добиат презентираните резултати. Со други зборови, пред вас е задача за повторлива анализа
Пример 2: Работите во индустриска лабораторија каде што вашата работа е да правите статистичка обработка на експериментални резултати или анализи за контрола на квалитет. Вашата организација повторно фунцкионира преку надворешни грантови или клиенти кои очекуваат дека резултатите од вашата лабораторија ќе може да бида независно потврдени. Во пракса ова повторно значи објавување на повторлив проект, со податоци и програмски код, кој што ќе фунцкионира во контекст многу различен од вашата лабораторија.
Пример 3: Накратко, бидејќи патернот е јасен. Вие сте научен истражувач на некој универзитет или институт. Вашата работа зависи од објавување трудови и аплицирање за грантови. Се поголем број на научни журнали имаат стриктни барања за транспарентни и повторливи анализи без кои нема ни да го рецензираат трудот. Вас ви треба повторлив проект.
Веројатно е полесно да се зборува за кого овој прирачник \emph{не е} корисен? Доколку се чувствувате како експерт по сите алатки спомнати во Поглавје \ref{tools}, тогаш веројатно нема да научите многу од овој текст. Сепак, овој прирачник наменет за почетници или искусни истражувачи но без пракса за повторливи анализи. Но тоа не значи дека не можете да помогнете со пријателска рецензија или со подобрување на некое поглавје каде што чувствувате дека има простор за значајно подобрување.
\hypertarget{organ}{%
\section{Организација}\label{organ}}
Темата на овој текст е доволно опширна што тука нема ни да се обидеме да дадеме севкупен третмант на сите значајни аспекти. Туку, целта е да дадеме преглед на главните принципи за повторливи анализи и практични примери за главните препораки.
По воведот, прво ќе се запознаеме со софтверските алатки кои ќе ги користиме понатаму (Поглавје \ref{tools}: Алатки), и ќе посочиме некои од најчестите случаи кога една анализа, дури и да имаме најдобри намери, може да биде ``неповторлива`` (Поглавје \ref{nogood}: Aнализи што не може да се повторат). Понатаму ќе ги разгледаме главните начини на кои постоечки код за некоја анализа која е тешка да се повтори може да се конвертира во повторлива анализа (Поглавје \ref{conversion}: Конверзија во повторлив код). Следи вовед во таканаречено „писмено програмирање``, односно пишување на документи коишто ги покажуваат нашите размислувањa, претпоставки, хипотези, заедно со кодот што го користиме за нивно тестирање и резултатите од тие тестови (Поглавје \ref{rmd}: Повторливи документи / извештаи). Во Поглавје \ref{proekti} ќе видиме како да организираме еден поголем проект, со неколку различни извори на податоци, скрипти, извештаи и резултати, во еден пакет со документација и стандардна структура што е лесна да се следи и користи. За крај, ќе зборуваме за контола на изворниот код со \texttt{git} што ни дава слобода и безбедност за променување и подобрување (Поглавје \ref{git}: Контрола на изворниот код). Текстот го затвораме со заклучок и литература со препорака во најмала рака да ги погледнете ресурсите дадени во библиографијата бидејќи содржат далеку подетални и ефективни третмани на темата на повторливо ракување, анализирање и објавување на податоци.
\hypertarget{ux437ux430-ux43eux432ux43eux458-ux43fux440ux438ux440ux430ux447ux43dux438ux43a}{%
\section{За овој прирачник}\label{ux437ux430-ux43eux432ux43eux458-ux43fux440ux438ux440ux430ux447ux43dux438ux43a}}
Овој прирачник е изработен како дел од проектот „Отворени податоци за отворена иднина``, поддржан од програмата Цивика Мобилитас, а спроведен од Слободен софтвер Македонија.
Содржината на овој прирачник е единствена одговорност на Слободен софтвер Македонија и на ниту еден начин не може да се смета дека ги одразува гледиштата на Цивика мобилитас, Швајцарската агенција за развој и соработка (SDC) или организациите што ја спроведуваат.
\hypertarget{tools}{%
\chapter{Алатки}\label{tools}}
\hypertarget{ux43fux440ux43eux433ux440ux430ux43cux441ux43aux438-ux458ux430ux437ux438ux43a-r}{%
\section{\texorpdfstring{Програмски јазик: \texttt{R}}{Програмски јазик: R}}\label{ux43fux440ux43eux433ux440ux430ux43cux441ux43aux438-ux458ux430ux437ux438ux43a-r}}
Генерално земено, во денешно време, доколку анализирате податоци тоа веројатно го правите со помош на \texttt{Python} \citep{rossum1995python} (и пакети како: \texttt{pandas} \citep{mckinney2011pandas}, \texttt{numpy} \citep{harris2020array}, \texttt{matplotlib} \citep{barrett2005matplotlib}) или \texttt{R} \citep{R} (со пакети како: \texttt{dplyr} \citep{R-dplyr}, \texttt{data.table} \citep{R-data.table}, \texttt{ggplot2} \citep{R-ggplot2}). Доколку работите на пониско ниво или вашата работа е поблиска до математика, можеби користите \texttt{c\#} за побрз код, но генерално, ретко кога јазик од типот на \texttt{c\#} сe користи за интерактивна анализа на податоци, графирање, или машинско учење. Понови, и помалку распространети, јазици како \texttt{Julia} \citep{bezanson2017julia} имаат дополнителни предности со тоа што овозможуваат лесно пишување код во истражувачки сесии како \texttt{Python} или \texttt{R} но со брзина на компутација што е поблиска до \texttt{c\#}. Во секој случај, препораките дадени во овој текст се апликабилни без разлика на програмскиот јазик што го користите.
Во овој текст генерално ќе работиме со софтверски алатки од \texttt{R} екосистемот. \texttt{R} е програмски јазик пред се наменет кон статистички анализи, и иако не е најраспространет или најшироко користен, е од особено значење за анализа на податоци, и следствено повторлива анализа на податоци. Главните причини за употребата на \texttt{R} авторите на овој текст секојдневно користат \texttt{R} и \texttt{Rstudio} и поради тоа што има еден куп дополнителни екстензии во оваа средина кои овозможуваат лесно пишување на повторливи технички извештаи, научни трудови (\texttt{Rmarkdown} \citep{R-rmarkdown}), книги (\texttt{bookdown} \citep{R-bookdown}), веб апликации (\texttt{shiny} \citep{R-shiny}), блогови (\texttt{blogdown} \citep{R-blogdown}), итн. Самиот овој текст го пишувамe со помош на \href{https://bookdown.org/}{\texttt{bookdown}}, што овозможува неверојатно лесно составање и објавивање на подолги текстови (книги) со поглавја, компјутерски код, и математичка нотација со едно копче во \texttt{Rstudio}. Заедницата на корисници на \texttt{R} е веројатно една од најактивните кога станува збор за повторливи анализи. На пример, организацијата \href{https://ropensci.org/}{\texttt{rOpenSci}} комплетно посветена кон поддршка и развој за алатки (\texttt{R} библиотеки) за транспарентни, повторливи истражувања. За горе-долу комплетна листа на ресурси поврзани со оваа тема, посетете ја CRAN (Comprehensive R Archive Network) страницата посветена на повторлива наука: \href{https://cran.r-project.org/web/views/ReproducibleResearch.html}{CRAN Task View: Reproducible Research}.
Во овој текст немаме намера да навлегуваме длабоко во самото кодирање во \texttt{R}. Нашиот приод ќе биде да објасниме одреден принцип со обични зборови и да покажеме како тоа би можело да изгледа со \texttt{R} код. Што значи, дури и да не знаете ништо за \texttt{R} би можеле да го следите текстот и да ги употребите препораките во вашиот омилен програмски јазик за обработка на податоци.
Во некои делови ќе користиме материјали кои се специфични за \texttt{R} и \texttt{Rstudio} (на пример \texttt{Rmarkdown}) така што можеби ќе има технички детали кои нема да може да директно да ги примените во \texttt{Jypiter} тетратка или доколку работите во друг текст едитор (\texttt{VScode}). Но повторно, имајќи предвид дека препораките ќе тежнеат кон тоа како да пишуваме код којшто ќе бара минимална интервенција при (ре)анализа на податоци, ваквите аспекти специфични за \texttt{Rstudio} ќе бидат сведени на минимум. Генерално, целта ни е да креираме пакет (фолдер) за правење пита што вклучува се што е неопходно за нашиот пријател да може без многу мислење да ја направи истата пита. За да го олесниме овој процес, треба да се стремиме кон тоа да не користиме специјален тарун (софтвер) за да ги сукаме корите, бидејќи таков тарун можеби нема да биде лесно достапен за нашиот пријател. Со други зборови, повторувањето на нашите резултати генерално не треба да зависи од едиторот за текст којшто ние го користиме.
\hypertarget{ux438ux43dux441ux442ux430ux43bux430ux446ux438ux458ux430}{%
\section{Инсталација}\label{ux438ux43dux441ux442ux430ux43bux430ux446ux438ux458ux430}}
Во овој прирачник нема многу програмски код кој би требало да го извршите додека читате --- целта секако ни е да не го направиме текстот премногу врзан со \texttt{R}. Но сепак, споменуваме некои \texttt{R} пакети и фунцкии кои можете да ги инсталирате со следниот код (под претпоставка дека веќе имате инсталирано \href{https://cloud.r-project.org/}{\texttt{R}} (со или без \href{https://rstudio.com/products/rstudio/download/}{\texttt{Rstudio}} )):
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# Извршете го следниот код}
\CommentTok{\# за да ги инсталирате сите }
\CommentTok{\# пакети користени во овој водич}
\NormalTok{paketi }\OtherTok{\textless{}{-}} \FunctionTok{c}\NormalTok{(}
\StringTok{"readr"}\NormalTok{,}
\StringTok{"dplyr"}\NormalTok{,}
\StringTok{"docopt"}\NormalTok{,}
\StringTok{"assertthat"}\NormalTok{,}
\StringTok{"devtools"}\NormalTok{,}
\StringTok{"usethis"}\NormalTok{,}
\StringTok{"prodigenr"}\NormalTok{,}
\StringTok{"rmarkdown"}\NormalTok{,}
\StringTok{"knitr"}
\NormalTok{)}
\FunctionTok{install.packages}\NormalTok{(}\AttributeTok{pkgs =}\NormalTok{ paketi)}
\end{Highlighting}
\end{Shaded}
\hypertarget{ux43aux43eux43dux442ux440ux43eux43bux430-ux43dux430-ux438ux437ux432ux43eux440ux435ux43d-ux43aux43eux434-git}{%
\section{\texorpdfstring{Контрола на изворен код: \texttt{git}}{Контрола на изворен код: git}}\label{ux43aux43eux43dux442ux440ux43eux43bux430-ux43dux430-ux438ux437ux432ux43eux440ux435ux43d-ux43aux43eux434-git}}
Контрола на изворниот код, најчесто со \texttt{git} (поглавје \ref{git}), е платформата што ни дава безбедност и слобода во секоја активност поврзана со програмски код, вклучително и при анализирање и ревизирање анализи на податоци. Во основа, \texttt{git} e систем за \texttt{undo}/\texttt{redo} на стероиди, што може да следи две или повеќе верзии на изворниот код (гранки), од два или повеќе компјутери, овозможува соработници од различни локации истовремено да праваt поправки и унапредувања без да си ги пребришуваат промените, и дозволува да се вратите на верзијата од пред два месеци без да ги изгубите меѓувремени промени. Во денешно време е невозможно да се замисли организација која зависи од програмски код за дел од своите фунцкии без употреба на \texttt{git} (или друг систем на контрола на изворен код). Стриктно гледано, \texttt{git} не е неопходен за правење повторливи анализи. Можно е да напишеме и споделиме скрипта која обработува некои податоците без да ги следиме промените на тој код. Но имајќи во предвид дека при обработка на податоци постојано се соочуваме со одлуки и ревизии, веројатно е ќе се најдеме на брег на река каде што ќе сакаме целиот товар да го спакуваме во водоотпорена вреќа пред да ја преминеме реката. \texttt{git} го овозможува токму тоа и скоро сигурно ќе го користите доколку работите на транспарентната анализа на податоци.
\hypertarget{ux440ux435ux437ux438ux43cux435-1}{%
\section{Резиме}\label{ux440ux435ux437ux438ux43cux435-1}}
Корисно е да ги табулираме овие алатки во споредба со компонентите кои ги воведовме претходно во поглавје \ref{analogy}):
\begin{table}
\caption{\label{tab:unnamed-chunk-2}Компонентите на повторување на анализа со соодветните софтверски алатки.}
\centering
\begin{tabular}[t]{l|l|l}
\hline
Аналог & Компонента & Алатка\\
\hline
Состојки & Податоци & csv, MySQL\\
\hline
Рецепта & Изворен код & R скрипта со git контрола\\
\hline
Алатки & Зависности на кодот & dplyr, ggplot2\\
\hline
Кујна & Виртуелен контејнер & docker (во следното издание)\\
\hline
\end{tabular}
\end{table}
\hypertarget{nogood}{%
\chapter{Анализи што не може да се повторат}\label{nogood}}
\hypertarget{typical}{%
\section{Типична анализа (која никој, дури ни авторот, не може да ја повтори)}\label{typical}}
Да погледнеме една хипотетичка но веројатно честа ситуација. Вие работите на некој проект што се однесува на податоци за сточарство во Македонија. Поврзани сте со локална дата база, имате големо парче податоци вчитани во меморија и работна средина со 10 закачени \texttt{R} пакети (библиотеки).
Ви стигнува ургентна е-пошта од колега кој бара да се направи сумирање на месечните трошоци на работа групирано по тип на трошок и по вработен. Вие велите, ах, ајде ова на брзина, ги снимате податоците во \texttt{Downloads} и почнувате:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(}\StringTok{"\textasciitilde{}/Downloads/trosoci{-}moja{-}firma.csv"}\NormalTok{)}
\NormalTok{trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }
\AttributeTok{path =} \StringTok{"\textasciitilde{}/Download/trosoci{-}moja{-}firma{-}sumirani.csv"}\NormalTok{)}
\end{Highlighting}
\end{Shaded}
За пет минути сте готови со минимална дистракција, па дури и не мрднавте од претходниот проект. Ја праќате новата табела на колегата. Супер. Фала многу.
Половина час подоцна стигнува е-пошта од претпоставениот со пофалба за брзо завршената работа и соработката со колегата. Шефицата исто вели ајде прати ни го кодот за да го забрзаме процесот во иднина и да не одземаме време од комплексните анализи кои ви се примарна задача. Вие го копирате кодот од историја на вашето \texttt{Rstudio} и го праќате:
\begin{verbatim}
trosoci <- read_csv("~/Downloads/trosoci-moja-firma.csv")
trosoci_sumirani <- trosoci %>%
group_by(vraboten, tip_na_trosok) %>%
summarise_at("cena", "sum") %>%
arrange(vraboten, tip_na_trosok)
write_csv(trosoci_sumirani,
path = "~/Download/trosoci-moja-firma-sumirani.csv")
\end{verbatim}
Но, како што можеби веќе очекувате, приказната не завршува тука. Стигнува нова пошта со пораката: "Кај мене ова не работи?!?{}`` Зошто? Па има неколку можни причини:
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\item
Првата линија код чита податоци од \texttt{\textasciitilde{}/Downloads/trosoci-moja-firma.csv}. Зошто претпоставуваме дека колегите ќе ја имаат таа табела во тој фолдер? \textbf{Проблем со податоците (состојките)}
\item
Првата линија код чита податоци од \texttt{\textasciitilde{}/Downloads/trosoci-moja-firma.csv}. Зошто претпоставуваме дека колегата ќе работи на \texttt{Linux} а не \texttt{Windows} на пример, па дури и да ги имаат податоците во \texttt{Downloads} патеката до тој фолдер ќе биде различна (на пр. \texttt{C:\textbackslash{}Downloads)} не \texttt{\textasciitilde{}/Downloads})? \textbf{Проблем со податоците (состојките) и со кодот (рецептот)}
\item
Во кодот што го пративме, не вчитуваме никакви пакети, иако користиме функции од два нестандардни пакети во \texttt{R}: \href{https://www.rdocumentation.org/packages/readr/versions/1.3.1}{\texttt{readr}} \citep{R-readr} и \href{https://www.rdocumentation.org/packages/dplyr/versions/0.7.8}{\texttt{dplyr}} \citep{R-dplyr}. Ние не ги вчитавме овие пакети бидејќи беа закачени во проектот на којшто работевме претходно (сетете се дека не отворивме нов проект). Зошто претпоставуваме дека колегите ќе ги имаат овие пакети закачени во нивната работна средина? \textbf{Проблем со кодот (рецептот) и со зависности (алатки)}.
\end{enumerate}
Иако ова личи за тривијален пример, проблемите не се тривијални. Обидете се да екстраполирате кон сериозна анализа со 500 линии код и ќе видите дека е скоро невозможно да се следи процесот и повтори анализата (направи питате) без далеку поголема грижа околу кодот (рецептот).
Горе се главните проблеми кои ја прават нашата кратка анализа не-повторлива. Но има и уште неколку дополнителни забелешки:
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\setcounter{enumi}{3}
\item
Патеката \texttt{\textasciitilde{}/Downloads/trosoci-moja-firma.csv} е со голема веројатност надвор од работната папка за било кој од вработените. Веројатнио никој не работи во \texttt{Downloads}, туку во папка наменета за различни проекти.
\item
Дополнително, многу е често папки како \texttt{Downloads} да се бришат/празнат со цел да не чуваме застарени датотеки коишто повторно можеме да ги преземеме. Значи за една недела, дури ни ние самите можеби нема да можеме да ја повториме анализата бидејќи датотеката ќе биде избришана.
\item
На втората команда во нашиот код, ние ја користиме функцијата \href{https://www.rdocumentation.org/packages/dplyr/versions/0.7.8/topics/summarise_all}{\texttt{summarise\_at}} којашто е едноставен начин да дадеме инструкција да се сумираат цените. Но, зависно од верзијата на \texttt{R} и \texttt{dplyr}, функцијата \texttt{summarise\_at} можеби нема да биде достапна. Доколку вашиот колега користи многу стара верзија на \texttt{dplyr}, функцијата \texttt{summarise\_at} нема да биде дел од тој пакет со таа верзија, додека со најновата верзија на \texttt{dplyr}, ќе добиеме предупредување за \texttt{summarise\_at} дека наскоро ќе биде заменета со подобра алтернатива. Се разбира овие детали не се толку битни, но веројатно е очигледна поентата дека треба да укажеме која верзија од некој пакет сме ја користеле за да може да се повтори нашата анализа.
\item
Патеката која ја користиме за да ја зачуваме табелата е фиксна, што значи ако сакаме да ја повториме процедурата за некоја друга табела, при зачувување ќе ја пребришеме првата зачувана табела.
\end{enumerate}
Значи, во навидно едноставна задача, што може да се заврши со три линии код, ние прекршивме неколку правила за безбедна пракса при анализирање на податоци. Во ова сценарио, дури ни оригиналниот автор на кодот не би можел да гарантира дека ќе може да ја повтори обработката на податоците во иднина.
\hypertarget{indicators}{%
\section{Типични пракси кои доведуваат до не-повторливи анализи}\label{indicators}}
Корисно е да споменеме некои од главните пракси кои доведуваат до ситуации како примерот погоре. Доколку при анализа на податоци некој аспект од вашата средина наликува на некоја од овие забелешки, тогаш имајте предвид дека вашата анализа може да биде проблематична за повторување. Генерално, обидете се да ги идентификувате и корегирате ваквите проблеми што е можно порано, бидејќи никој од нас не сака да менува код од стотици линии или да заменува библиотека откако сме завршиле пола од работата.
\begin{itemize}
\item
Податоците и кодот не се сместени во истиот директориум. На пример податоци во \texttt{C:/Data}, а код во \texttt{C:/Analizi}.
\item
Кодот користи апсолутни патеки за вчитување или зачувување на табели (на пример: \texttt{C:/Data/Мај2020/трошоци/}). Ваквите апсолутни патеки со голема сигурност не се портабилни.
\item
Код без документација (коментари кои типично почнуваат со \#) или \texttt{README} фајл кој ќе укаже како, по кој редослед да се користат скриптите и кои податоци се користат во која скрипта или кој график.
\item
Код без повикани зависности (користени библиотеки) и без информација за верзиите на повиканите зависности.
\item
Објекти со податоци кои не се експлицитно вчитани со код (укажува на податоци кои се во нашата работна средина но веројатно \emph{нема} да бидат достапни за други).
\item
Работиме на нешто што вклучува случајност (randomness) но немаме наместено зачеток за генераторот на рандом бројки (\href{https://www.rdocumentation.org/packages/simEd/versions/1.0.3/topics/set.seed}{\texttt{set.seed}} во \texttt{R}). Ова се случува секогаш кога делиме податоци на сетови за тренирање и тестирање во машинско учење на пример.
\end{itemize}
Очекуваме дека оваа листа ќе расте како што овој текст напредува понатаму.
\hypertarget{conversion}{%
\chapter{Конверзија во повторлив код}\label{conversion}}
\hypertarget{ux43fux43eux434ux430ux442ux43eux446ux438}{%
\section{Податоци}\label{ux43fux43eux434ux430ux442ux43eux446ux438}}
За да може да ги видиме следните чекори во акција неопходни ни се податоци. Табелата за трошоци има три колони (варијабли) \texttt{vraboten}, \texttt{tip\_na\_trosok} и \texttt{cena}. Еве ги првите неколку редови:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{trosoci}
\end{Highlighting}
\end{Shaded}
\begin{verbatim}
## # A tibble: 30 x 3
## vraboten tip_na_trosok cena
## <chr> <chr> <dbl>
## 1 Ана И. печатење 75
## 2 Ристе Н. транспорт 81
## 3 Ана И. печатење 13
## 4 Благоја В. канцелариски материјали 40
## 5 Антонија А. транспорт 89
## 6 Љупчо В. печатење 48
## 7 Благоја В. канцелариски материјали 96
## 8 Љупчо В. канцелариски материјали 23
## 9 Љупчо В. транспорт 84
## 10 Ана И. печатење 29
## # ... with 20 more rows
\end{verbatim}
Трансформацијата која ја прави нашиот, сѐ уште неповторлив, код можеме исто така да ја видиме во акција:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\end{Highlighting}
\end{Shaded}
\begin{verbatim}
## # A tibble: 12 x 3
## # Groups: vraboten [5]
## vraboten tip_na_trosok cena
## <chr> <chr> <dbl>
## 1 Ана И. канцелариски материјали 31
## 2 Ана И. печатење 177
## 3 Ана И. транспорт 51
## 4 Антонија А. печатење 324
## 5 Антонија А. транспорт 111
## 6 Благоја В. канцелариски материјали 196
## 7 Благоја В. печатење 218
## 8 Благоја В. транспорт 54
## 9 Љупчо В. канцелариски материјали 23
## 10 Љупчо В. печатење 48
## 11 Љупчо В. транспорт 127
## 12 Ристе Н. транспорт 116
\end{verbatim}
\hypertarget{ux43fux440ux432ux438-ux447ux435ux43aux43eux440ux438-ux43aux43eux43d-ux43fux43eux432ux442ux43eux440ux43bux438ux432ux43eux441ux442}{%
\section{Први чекори кон повторливост}\label{ux43fux440ux432ux438-ux447ux435ux43aux43eux440ux438-ux43aux43eux43d-ux43fux43eux432ux442ux43eux440ux43bux438ux432ux43eux441ux442}}
Откако сме ги согледале проблемите што доведуваат до тоа резултатот од нашиот код да не може да се повтори (без колегата да почне да чепка и кодира од почеток), можеме да интервенираме. За нашиот код да биде повторлив, минимално треба:
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\item
Да ги повикува \texttt{R} пакетите кои се неопходни за функциите што ги користиме
\item
Да не користи апсолутни патеки за вчитување и зачувување на патоци коишто се надвор од фолдерот во кој што е сместена самата скрипта
\item
Да биде детално документиран
\end{enumerate}
Што се однесува до првиот проблем, кодот едноставно нема да работи без пакетите \href{https://www.rdocumentation.org/packages/readr/versions/1.3.1}{\texttt{readr}} \citep{R-readr} и \href{https://www.rdocumentation.org/packages/dplyr/versions/0.7.8}{\texttt{dplyr}} \citep{R-dplyr} да се вчитани па дури и нашиот колега да ги има истите фајлови на истите локации како ние. Оваа корекција е едноставна:
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# Вчитај ги ти пакетите кои се користат подолу }
\FunctionTok{library}\NormalTok{(dplyr)}
\FunctionTok{library}\NormalTok{(readr)}
\CommentTok{\# Доколку не се достапни, инсталирај од CRAN со:}
\CommentTok{\# install.packages("dplyr")}
\CommentTok{\# install.packages("readr")}
\NormalTok{trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(}\StringTok{"data/trosoci{-}moja{-}firma.csv"}\NormalTok{)}
\NormalTok{trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }
\AttributeTok{path =} \StringTok{"data/trosoci{-}moja{-}firma{-}sumirani.csv"}\NormalTok{)}
\end{Highlighting}
\end{Shaded}
Што се однесува до втората задача, имаме повеќе можности. Можеме да побараме корисникот да ја зачува патеката во варијабла која ќе биде користена од понатамошниот код. Ова се уште дозволува патеки во друг директориум, и очигледно бара соодветна интервенција од корисникот, но ако ништо друго, корисникот на овој код, доколку ја прочита документацијата (значи снаоѓањето \emph{зависи} од нашата инвестиција кон добра документација), може барем да ја повтори анализата без да добие грешки:
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# Вчитај ги ти пакетите кои се користат подолу }
\FunctionTok{library}\NormalTok{(dplyr)}
\FunctionTok{library}\NormalTok{(readr)}
\CommentTok{\# Доколку не се достапни, инсталирај со:}
\CommentTok{\# install.packages("dplyr")}
\CommentTok{\# install.packages("readr")}
\CommentTok{\# ВНИМАНИЕ:}
\CommentTok{\# Скриптата нема да работи доколку не внесете валидни дестинации}
\CommentTok{\# за фајлови за вчитување и зачувување}
\NormalTok{pateka\_do\_input }\OtherTok{\textless{}{-}} \ConstantTok{NULL} \CommentTok{\# "data/trosoci{-}moja{-}firma.csv"}
\NormalTok{pateka\_za\_output }\OtherTok{\textless{}{-}} \ConstantTok{NULL} \CommentTok{\# "data/trosoci{-}moja{-}firma{-}sumirani.csv"}
\CommentTok{\# На пример:}
\CommentTok{\# pateka\_do\_input \textless{}{-} "\textasciitilde{}/Downloads/trosoci{-}moja{-}firma.csv" }
\CommentTok{\# pateka\_do\_output \textless{}{-} "\textasciitilde{}/Downloads/trosoci{-}moja{-}firma{-}sumirani.csv" }
\CommentTok{\# или:}
\CommentTok{\# pateka\_do\_input \textless{}{-} "C:\textbackslash{}rabota\textbackslash{}podatoci\textbackslash{}trosoci\textbackslash{}trosoci{-}moja{-}firma.csv"}
\CommentTok{\# pateka\_do\_output \textless{}{-} "C:\textbackslash{}rabota\textbackslash{}podatoci\textbackslash{}trosoci\textbackslash{}trosoci{-}moja{-}firma{-}sumirani.csv"}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(pateka\_do\_input)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }
\AttributeTok{path =}\NormalTok{ pateka\_za\_output)}
\end{Highlighting}
\end{Shaded}
\hypertarget{ux444ux443ux43dux43aux446ux438ux458ux430}{%
\section{Функција}\label{ux444ux443ux43dux43aux446ux438ux458ux430}}
Алтернатива која бара малку поголема подготовка е да го напишеме функција којашто ќе работи на ист начин, земајќи ги патеките како аргументи:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{sumiraj\_trosoci }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(trosoci, destinacija) \{}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{ trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(trosoci)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{ trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani,}
\AttributeTok{path =}\NormalTok{ destinacija)}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
Често, сакаме табелата којашто ја снимаме да го има истото основно име како табелата што ја трансформираме (на пример \texttt{moja-tabela.csv} и \texttt{moja-tabela-medijani.csv}) и да се наоѓа во истиот фолдер. Со малку манипулација на текст во \texttt{R} (ова е уште полесно во \texttt{Python}) добиваме:
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# Функција за групирање и сумирање трошоци}
\CommentTok{\# Аргументот \textasciigrave{}trosoci\textasciigrave{} е патека до табелата што треба да се трансформира}
\NormalTok{sumiraj\_trosoci }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(trosoci\_tabela) \{}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{ trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(trosoci\_tabela)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{ trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Направи патека за дестинација}
\NormalTok{ folder\_name }\OtherTok{\textless{}{-}} \FunctionTok{dirname}\NormalTok{(trosoci\_tabela)}
\NormalTok{ base\_name }\OtherTok{\textless{}{-}}\NormalTok{ tools}\SpecialCharTok{::}\FunctionTok{file\_path\_sans\_ext}\NormalTok{(}\FunctionTok{basename}\NormalTok{(trosoci\_tabela))}
\NormalTok{ new\_name }\OtherTok{\textless{}{-}} \FunctionTok{paste}\NormalTok{(base\_name, }\StringTok{"sumirani.csv"}\NormalTok{, }\AttributeTok{sep=}\StringTok{"{-}"}\NormalTok{)}
\NormalTok{ destinacija }\OtherTok{\textless{}{-}} \FunctionTok{file.path}\NormalTok{(folder\_name, new\_name)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }\AttributeTok{path =}\NormalTok{ destinacija)}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
Целата скрипта по овие промени би изгледала вака:
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# Употреба:}
\CommentTok{\# Вчитај ја оваа скипта во R за да ја користиш функцијата \textasciigrave{}sumiraj\_trosoci\textasciigrave{} }
\CommentTok{\# Вчитај ги ти пакетите кои се користат подолу }
\FunctionTok{library}\NormalTok{(dplyr)}
\FunctionTok{library}\NormalTok{(readr)}
\CommentTok{\# Доколку не се достапни, инсталирај со:}
\CommentTok{\# install.packages("dplyr")}
\CommentTok{\# install.packages("readr")}
\CommentTok{\# Функција за групирање и сумирање трошоци}
\CommentTok{\# Аргументот \textasciigrave{}trosoci\textasciigrave{} е патека до табелата што треба да се трансформира}
\NormalTok{sumiraj\_trosoci }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(trosoci\_tabela) \{}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{ trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(trosoci\_tabela)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{ trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Направи патека за дестинација}
\NormalTok{ folder\_name }\OtherTok{\textless{}{-}} \FunctionTok{dirname}\NormalTok{(trosoci\_tabela)}
\NormalTok{ base\_name }\OtherTok{\textless{}{-}}\NormalTok{ tools}\SpecialCharTok{::}\FunctionTok{file\_path\_sans\_ext}\NormalTok{(}\FunctionTok{basename}\NormalTok{(trosoci\_tabela))}
\NormalTok{ new\_name }\OtherTok{\textless{}{-}} \FunctionTok{paste}\NormalTok{(base\_name, }\StringTok{"sumirani.csv"}\NormalTok{, }\AttributeTok{sep=}\StringTok{"{-}"}\NormalTok{)}
\NormalTok{ destinacija }\OtherTok{\textless{}{-}} \FunctionTok{file.path}\NormalTok{(folder\_name, new\_name)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }\AttributeTok{path =}\NormalTok{ destinacija)}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
Што сме постигнале до сега? Зависностите на кодот се решени. Документација имаме, впрочем, пишување на коментари во кодот треба да стане навика. И имаме функција на која може да и дадеме табела која што се наоѓа било каде и да зачуваме сумирана табела во истата папка.
\hypertarget{rscript-ux448ux442ux43e-ux43cux43eux436ux435-ux434ux430-ux433ux43e-ux43aux43eux440ux438ux441ux442ux438ux43cux435-ux431ux435ux437-ux434ux430-ux43eux442ux432ux430ux440ux430ux43cux435-r}{%
\section{\texorpdfstring{Rscript што може да го користиме без да отвараме \texttt{R}}{Rscript што може да го користиме без да отвараме R}}\label{rscript-ux448ux442ux43e-ux43cux43eux436ux435-ux434ux430-ux433ux43e-ux43aux43eux440ux438ux441ux442ux438ux43cux435-ux431ux435ux437-ux434ux430-ux43eux442ux432ux430ux440ux430ux43cux435-r}}
Нашиот код е далеку подобар и има повеќе шанси да работи на други компјутери, но се уште може да се каже дека има некои недостатоци. На пример, корисникот \emph{мора} да отвори \texttt{R}, да ја вчита скриптата, и да ја изврши функцијата. Тоа е можеби во ред доколку нашиот колега има доволно познавање од \texttt{R}, но можеби нашиот шеф не знае \texttt{R} или едноставно нема време за чепкање во \texttt{R} терминал. Можеби сака решение од една линија налик на следното:
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{Rscript.exe}\NormalTok{ sumiraj\_trosoci.R trosoci\_dekemvri\_2020.csv}
\end{Highlighting}
\end{Shaded}
Да го конвертираме нашиот код во ваква скрипта е лесно. Доколку кодот го процесираме со \href{https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/Rscript}{\texttt{Rscript}}, треба само да го земеме името на датотеката даден по името на скриптата (тоа е табелата со трошоци), и да го предадеме на нашата функција (внатре во скриптата):
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# (data/sumiraj{-}trosoci{-}1.R)}
\CommentTok{\# Употреба:}
\CommentTok{\# Вчитај ја оваа скипта во R за да ја користиш функцијата \textasciigrave{}sumiraj\_trosoci\textasciigrave{} }
\CommentTok{\# Закачи ги ти пакетите кои се користат подолу }
\FunctionTok{library}\NormalTok{(dplyr)}
\FunctionTok{library}\NormalTok{(readr)}
\CommentTok{\# Доколку не се достапни, инсталирај со:}
\CommentTok{\# install.packages("dplyr")}
\CommentTok{\# install.packages("readr")}
\CommentTok{\# Функција за групирање и сумирање трошоци}
\CommentTok{\# Аргументот \textasciigrave{}trosoci\textasciigrave{} е патека до табелата што треба да се трансформира}
\NormalTok{sumiraj\_trosoci }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(trosoci\_tabela) \{}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{ trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(trosoci\_tabela)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{ trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Направи патека за дестинација}
\NormalTok{ folder\_name }\OtherTok{\textless{}{-}} \FunctionTok{dirname}\NormalTok{(trosoci\_tabela)}
\NormalTok{ base\_name }\OtherTok{\textless{}{-}}\NormalTok{ tools}\SpecialCharTok{::}\FunctionTok{file\_path\_sans\_ext}\NormalTok{(}\FunctionTok{basename}\NormalTok{(trosoci\_tabela))}
\NormalTok{ new\_name }\OtherTok{\textless{}{-}} \FunctionTok{paste}\NormalTok{(base\_name, }\StringTok{"sumirani.csv"}\NormalTok{, }\AttributeTok{sep=}\StringTok{"{-}"}\NormalTok{)}
\NormalTok{ destinacija }\OtherTok{\textless{}{-}} \FunctionTok{file.path}\NormalTok{(folder\_name, new\_name)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }\AttributeTok{path =}\NormalTok{ destinacija)}
\NormalTok{\}}
\CommentTok{\# Земи го првиот аргумент}
\NormalTok{dadeni\_trosoci }\OtherTok{\textless{}{-}} \FunctionTok{commandArgs}\NormalTok{(}\AttributeTok{trailingOnly=}\ConstantTok{TRUE}\NormalTok{)[[}\DecValTok{1}\NormalTok{]]}
\CommentTok{\# Изврши ја функцијата}
\FunctionTok{sumiraj\_trosoci}\NormalTok{(}\AttributeTok{trosoci =}\NormalTok{ dadeni\_trosoci)}
\end{Highlighting}
\end{Shaded}
Доколку го тестирате кодот додека читате го имате преземено директориумот за овој текст, оваа скрипта и податоците за трошоци се наоѓаат како фолдерот \textbf{\texttt{data}} под името \textbf{\texttt{sumiraj-trosoci-1.R}} и \textbf{\texttt{trosoci-moja-firma.csv}}.
Доколку сакаме навистина да се потрудиме, како поради безбедност така и поради лесно користење на ваквата скрипта, можеме да додадеме кратко упатство за користење, и код за проверка на аргументот.
За да направиме упатство за користење, ќе го користиме пакетот \href{https://www.rdocumentation.org/packages/docopt/versions/0.7.1}{\texttt{docopt}} кој што користи таканаречен \href{https://en.wikipedia.org/wiki/Docstring}{\texttt{docstring}}, односно текст којшто следи некои правила за форматирање со цел да биде лесно парсиран како прирачник за употреба на нашата скрипта. \texttt{docopt/docstring} имаат еквиваленти во сите други програмски јазици, така да доколку програмирате во \texttt{Python} или \texttt{Perl} \citep{wall2000programming} веројатно ви се веќе познати овие концепти.
За да провериме дека се е во ред со табелата што и е дадена на скриптата, ќе го користиме пакетот \href{https://www.rdocumentation.org/packages/assertthat/versions/0.2.1}{assertthat}, што ни овозможува лесни проверки и информативни пораки за грешката. Стриктно гледано, пакетите \texttt{docopt} и \texttt{assertthat} не се неопходни, можеме да користиме функции како \href{https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/commandArgs}{\texttt{commandArgs()}} и \href{https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/stopifnot}{\texttt{stopifnot()}} од основната дистрибуција на \texttt{R}. Но во некои случаи користење на додатни пакети навистина ја олеснува работата.
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# (data/sumiraj{-}trosoci{-}2.R)}
\StringTok{\textquotesingle{}Сумирај трошоци групирани по вработен и тип на трошок. }
\StringTok{ Табелаta со трошоци мора да ги содржи колоните: \textasciigrave{}vraboten\textasciigrave{}, \textasciigrave{}tip\_na\_trosok\textasciigrave{}, и \textasciigrave{}cena\textasciigrave{}.}
\StringTok{ }
\StringTok{ Usage:}
\StringTok{ sumiraj{-}trosoci{-}2.R \textless{}tabela\_so\_trosoci\textgreater{}}
\StringTok{ sumiraj{-}trosoci{-}2.R {-}{-}help}
\StringTok{ sumiraj{-}trosoci{-}2.R {-}{-}version}
\StringTok{ Options:}
\StringTok{ {-}{-}help Прикажи помош}
\StringTok{ {-}{-}version Прикажи верзија}
\StringTok{ }
\StringTok{\textquotesingle{}} \OtherTok{{-}\textgreater{}}\NormalTok{ doc}
\CommentTok{\# Логика за аргументи}
\FunctionTok{library}\NormalTok{(docopt)}
\NormalTok{arguments }\OtherTok{\textless{}{-}} \FunctionTok{docopt}\NormalTok{(doc, }\AttributeTok{version =} \StringTok{"Сумирај трошоци 2.0}\SpecialCharTok{\textbackslash{}n}\StringTok{"}\NormalTok{)}
\CommentTok{\# Провери дали табелата е csv формат}
\NormalTok{assertthat}\SpecialCharTok{::}\FunctionTok{assert\_that}\NormalTok{(}
\NormalTok{ assertthat}\SpecialCharTok{::}\FunctionTok{has\_extension}\NormalTok{(arguments}\SpecialCharTok{$}\NormalTok{tabela\_so\_trosoci, }\AttributeTok{ext =} \StringTok{"csv"}\NormalTok{))}
\CommentTok{\# Вчитај ги ти пакетите кои се користат подолу}
\FunctionTok{suppressPackageStartupMessages}\NormalTok{(\{}
\FunctionTok{library}\NormalTok{(dplyr)}
\FunctionTok{library}\NormalTok{(readr)}
\FunctionTok{library}\NormalTok{(assertthat)}
\NormalTok{\})}
\CommentTok{\# Доколку не се достапни, инсталирај со:}
\CommentTok{\# install.packages("dplyr")}
\CommentTok{\# install.packages("readr")}
\CommentTok{\# install.packages(assertthat)}
\CommentTok{\# Функција за групирање и сумирање трошоци}
\CommentTok{\# Аргументот \textasciigrave{}trosoci\_tabela\textasciigrave{} е патека до табелата што треба да се трансформира}
\NormalTok{sumiraj\_trosoci }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(trosoci\_tabela) \{}
\CommentTok{\# Вчитај ги податоците}
\NormalTok{ trosoci }\OtherTok{\textless{}{-}} \FunctionTok{read\_csv}\NormalTok{(trosoci\_tabela)}
\NormalTok{ assertthat}\SpecialCharTok{::}\FunctionTok{assert\_that}\NormalTok{(}\FunctionTok{inherits}\NormalTok{(trosoci, }\StringTok{"data.frame"}\NormalTok{), }\AttributeTok{msg =} \StringTok{"Табелата не беше вчитана како \textasciigrave{}data.frame\textasciigrave{}."}\NormalTok{)}
\NormalTok{ assertthat}\SpecialCharTok{::}\FunctionTok{assert\_that}\NormalTok{(}\FunctionTok{all}\NormalTok{(}\FunctionTok{c}\NormalTok{(}\StringTok{"vraboten"}\NormalTok{, }\StringTok{"tip\_na\_trosok"}\NormalTok{, }\StringTok{"cena"}\NormalTok{) }\SpecialCharTok{\%in\%} \FunctionTok{names}\NormalTok{(trosoci)), }
\AttributeTok{msg =} \StringTok{"Табелата мора да содржи колони со имињата: \textquotesingle{}vraboten\textquotesingle{}, \textquotesingle{}tip\_na\_trosok\textquotesingle{}, \textquotesingle{}cena\textquotesingle{}."}\NormalTok{)}
\NormalTok{ assertthat}\SpecialCharTok{::}\FunctionTok{assert\_that}\NormalTok{(}\FunctionTok{is.numeric}\NormalTok{(trosoci}\SpecialCharTok{$}\NormalTok{cena), }\AttributeTok{msg =} \StringTok{"Колоната \textasciigrave{}cena\textasciigrave{} мора да биде нумеричка."}\NormalTok{)}
\CommentTok{\# Групирај и пресметај суми}
\NormalTok{ trosoci\_sumirani }\OtherTok{\textless{}{-}}\NormalTok{ trosoci }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{group\_by}\NormalTok{(vraboten, tip\_na\_trosok) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{summarise\_at}\NormalTok{(}\StringTok{"cena"}\NormalTok{, }\StringTok{"sum"}\NormalTok{) }\SpecialCharTok{\%\textgreater{}\%}
\FunctionTok{arrange}\NormalTok{(vraboten, tip\_na\_trosok)}
\CommentTok{\# Направи патека за дестинација}
\NormalTok{ folder\_name }\OtherTok{\textless{}{-}} \FunctionTok{dirname}\NormalTok{(trosoci\_tabela)}
\NormalTok{ base\_name }\OtherTok{\textless{}{-}}\NormalTok{ tools}\SpecialCharTok{::}\FunctionTok{file\_path\_sans\_ext}\NormalTok{(}\FunctionTok{basename}\NormalTok{(trosoci\_tabela))}
\NormalTok{ new\_name }\OtherTok{\textless{}{-}} \FunctionTok{paste}\NormalTok{(base\_name, }\StringTok{"sumirani.csv"}\NormalTok{, }\AttributeTok{sep=}\StringTok{"{-}"}\NormalTok{)}
\NormalTok{ destinacija }\OtherTok{\textless{}{-}} \FunctionTok{file.path}\NormalTok{(folder\_name, new\_name)}
\CommentTok{\# Зачувај}
\FunctionTok{write\_csv}\NormalTok{(trosoci\_sumirani, }\AttributeTok{path =}\NormalTok{ destinacija)}
\NormalTok{\}}
\CommentTok{\# Земи го првиот аргумент (табелата)}
\NormalTok{dadeni\_trosoci }\OtherTok{\textless{}{-}}\NormalTok{ arguments}\SpecialCharTok{$}\NormalTok{tabela\_so\_trosoci}
\CommentTok{\# Изврши ја функцијата}
\FunctionTok{sumiraj\_trosoci}\NormalTok{(}\AttributeTok{trosoci =}\NormalTok{ dadeni\_trosoci)}
\end{Highlighting}
\end{Shaded}
Со овие додатоци, нашата скрипта сега ќе може дури и да им помогне на корисниците доколку наидат на грешка. Сѐ уште не сме комплетно безбедни од не-повторливост, но стигнавме далеку имајќи во предвид каде почнавме. На пример, ако ја извршиме скриптата без аргументи:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{$ }\ExtensionTok{Rscript}\NormalTok{ sumiraj{-}trosoci{-}2.R }
\ExtensionTok{Error}\NormalTok{: Сумирај трошоци групирани по вработен и тип на трошок. }
\ExtensionTok{Табелаta}\NormalTok{ со трошоци мора да ги содржи колоните: }\KeywordTok{\textasciigrave{}}\ExtensionTok{vraboten}\KeywordTok{\textasciigrave{}}\NormalTok{, }\KeywordTok{\textasciigrave{}}\ExtensionTok{tip\_na\_trosok}\KeywordTok{\textasciigrave{}}\NormalTok{, и }\KeywordTok{\textasciigrave{}}\ExtensionTok{cena}\KeywordTok{\textasciigrave{}}\NormalTok{.}
\ExtensionTok{Usage}\NormalTok{:}
\ExtensionTok{sumiraj{-}trosoci{-}2.R} \OperatorTok{\textless{}}\NormalTok{tabela\_so\_trosoci}\OperatorTok{\textgreater{}}
\ExtensionTok{Execution}\NormalTok{ halted}
\end{Highlighting}
\end{Shaded}
Со коректен инпут:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{$ }\ExtensionTok{Rscript}\NormalTok{ sumiraj{-}trosoci{-}2.R trosoci{-}moja{-}firma.csv }
\NormalTok{[}\ExtensionTok{1}\NormalTok{] TRUE}
\ExtensionTok{Parsed}\NormalTok{ with column specification:}
\ExtensionTok{cols}\NormalTok{(}
\ExtensionTok{vraboten}\NormalTok{ = col\_character(),}
\ExtensionTok{tip\_na\_trosok}\NormalTok{ = col\_character(),}
\ExtensionTok{cena}\NormalTok{ = col\_double()}
\NormalTok{)}
\end{Highlighting}
\end{Shaded}
Со погрешен фајл, праќаме ексел наместо текстуална табела со запирки:
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{Rscript}\NormalTok{ sumiraj{-}trosoci{-}2.R trosoci{-}moja{-}firma.xls }
\ExtensionTok{Error}\NormalTok{: File }\StringTok{\textquotesingle{}trosoci{-}moja{-}firma.xls\textquotesingle{}}\NormalTok{ does not have extension csv}
\ExtensionTok{Execution}\NormalTok{ halted}
\end{Highlighting}
\end{Shaded}
Ако колоната за \texttt{cena} е крстена \texttt{eur}:
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{Rscript}\NormalTok{ sumiraj{-}trosoci{-}2.R trosoci{-}moja{-}firma{-}eur.csv}
\NormalTok{[}\ExtensionTok{1}\NormalTok{] TRUE}
\ExtensionTok{Parsed}\NormalTok{ with column specification:}
\ExtensionTok{cols}\NormalTok{(}
\ExtensionTok{vraboten}\NormalTok{ = col\_character(),}
\ExtensionTok{tip\_na\_trosok}\NormalTok{ = col\_character(),}
\ExtensionTok{eur}\NormalTok{ = col\_double()}
\NormalTok{)}
\ExtensionTok{Error}\NormalTok{: Табелата мора да содржи колони со имињата: }\StringTok{\textquotesingle{}vraboten\textquotesingle{}}\NormalTok{, }\StringTok{\textquotesingle{}tip\_na\_trosok\textquotesingle{}}\NormalTok{, }\StringTok{\textquotesingle{}cena\textquotesingle{}}\NormalTok{.}
\ExtensionTok{Execution}\NormalTok{ halted}
\end{Highlighting}
\end{Shaded}
\hypertarget{ux440ux435ux437ux438ux43cux435-2}{%
\section{Резиме}\label{ux440ux435ux437ux438ux43cux435-2}}
Во ова поглавје видовме како нашите едноставни три линии код напишани набрзина можеме да ги претвориме во постабилна скрипта која веќе ги има следните карактеристики значајни за повторливост:
\begin{itemize}
\tightlist
\item
Сите зависности на кодот се експлицитно наведени и пакетите се вчитани\\
\item
Скриптата \emph{не} зависи од нашата работна средина\\
\item
Имаме далеку подобра документација, како за корисници кои ќе го отворат фајлот, така и за тие кои само ќе ја вчитаат скриптата\\
\item
Имаме неколку проверки/валидации на табелата што се трансформира -- мора да осигураме дека табелата ги исполнува потребите пред да почнеме да сумираме\\
\item
Имаме автоматско составување на името за зачувување од коренот на името на табелата што ја праќаме во скриптата
\end{itemize}
Сите овие чекори придонесуваат до побезбедно и одбранбено (дефенсивно) програмирање, односно пракса која ги зголемува шансите дека некој код ќе работи како што се очекува надвор од контекстот во кој бил креиран. Во овој случај, контекстот на креирање беше нашата \texttt{R} сесија со 10 вчитани пакети и датотека зачувана во \texttt{\textasciitilde{}/Downloads} на \texttt{Linux} оперативен систем. Видовме дека и само еден од овие аспекти на работната средина да варира кај нашите колеги, нашата скрипта нема да работи без тие да почнат да го менуваат изворниот код. Но со наведените подобрувања ги предвидуваме и надминуваме голем дел од овие проблеми.
Независно, иако направиме голем напредок кон повторлива обработка на податоци, сѐ уште правиме некакви претпоставки за контекстот во кој скриптата ќе биде користена. На пример, претпоставуваме дека сите потенцијални корисници ќе имаат табелата со трошoци, дека сите корисници ќе имаат \texttt{R} и \texttt{Rscript} инсталирано за да можат да ја извршат скриптата, и дека сите корисници ќе ги имаат инсталирано библиотеките од кои зависи нашата скрипта. Во следните поглавја ќе разгледаме начини на кои може да составиме повторливи проекти кои вклучуваат многу скрипти и податоци и прават минимални претпоставки за средината во која некој ќе се обиде да ја повтори нашата анализа.
\hypertarget{rmd}{%
\chapter{Повторливи документи / извештаи со писмено програмирање (R + markdown)}\label{rmd}}
Во претходното поглавје, се запознавме со некои од главните методи за обезбедување на нашиот програмски код со цел да биде фунцкионален и на нечиј друг компјутер. Разгледавме ситуација со една скрипта и една табела со резултати, но доколку се запрашаме, сигурно ќе се согласиме дека речиси никогаш не е доволно да се испрати (или објави) само една табела или пресметка. Наспроти, често потребно е да се додаде текстуално објаснување или некаков друг контекст на податоците. Исто така, во многу случаи, нашите визуелизации во форма на табели или графици, или нашите статистички резултати (t-вредности, p-вредности, равенки за регресија), треба да ги прикажеме заедно со програмскиот код кој сме го напишале за да дојдеме то тие резултати.
За едноставно комбинирање на код, податоци, резултати и текст во еден документ, светот на \texttt{R} се користи \href{https://www.rdocumentation.org/packages/rmarkdown/versions/2.6}{\texttt{rmarkdown}} \citep{R-rmarkdown}. \texttt{rmarkdown} овозможува комбинирање на сите елементи на едно истражување во документ погоден за понатамошно споделување. Патем, така е напишан и овој прирачник, кој исто така цели да биде повторлив.
\hypertarget{ux444ux43eux440ux43cux430ux442ux438ux440ux430ux45aux435-ux43dux430-ux442ux435ux43aux441ux442-ux441ux43e-markdown}{%
\section{Форматирање на текст со markdown}\label{ux444ux43eux440ux43cux430ux442ux438ux440ux430ux45aux435-ux43dux430-ux442ux435ux43aux441ux442-ux441ux43e-markdown}}
Markdown, за разлика од \emph{markup} програмски јазици како \texttt{HTML} или \texttt{LaTeX} има за цел да го поедностави процесот на форматирање на текст. За детална референца на филозофијата и синтаксата на \texttt{markdown}, погледнете ги официјалните вебсајти нa \href{https://daringfireball.net/projects/markdown/syntax}{оригиналната спецификација} или поновата \href{https://commonmark.org/}{стандардизирана спецификација}. Во контекст на \texttt{R} и \texttt{Rstudio} погледнете го поглавјето за \href{https://r4ds.had.co.nz/r-markdown.html}{Rmarkdown во книгата R for Data Science} или \href{https://emilyriederer.netlify.app/post/rmarkdown-driven-development/}{овој блогпост} (и линковите таму) посветен на процесот на развивање на \texttt{R} код, или развивање на една анализа низ призмата на писмено програмирање со \texttt{rmarkdown} („писмено`` го преведуваме од англиското `literate programming').
Тука, накратко ќе ги споменеме најчестите компоненти. На пример, обичниот текст со мала декорација прикажан тука:
\begin{verbatim}
Оваа _реченица_ е напишана во **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$
\end{verbatim}
по процесирањето ќе биде конвертиран во следниот параграф:
\begin{quote}
Оваа \emph{реченица} е напишана во \textbf{markdown} но не е процесирана за да се покаже синтаксата.
На \href{https://kbroman.org/knitr_knutshell/pages/Rmarkdown.html}{овој линк} или
\href{https://rmarkdown.rstudio.com/authoring_quick_tour.html}{овој линк} можете да
прочитате повеќе за пишување \texttt{Rmarkdown}.
\end{quote}
\begin{quote}
За директни калкулации во текстот, користите ja следната синтакса: 6.28.
Kаде што првиот елемент на парчето (chunk) укажува како да го процесираме кодот што следи.
\textbf{За \texttt{R} користете \texttt{r}}. (Во ова не-процесирано парче, ние користиме кирилично \texttt{р} токму со
цел на тоа да ја покажеме синтакста без да го конвертираме кодот во пресметаната вредност.)
\end{quote}
\begin{quote}
За прикажување математичка нотација, користете: \(P = r^2 * \pi\)
\end{quote}
Забележуваме дека е навистина еднотавно да се куца обичен текст кој во \texttt{HTML}, \texttt{PDF}, или \texttt{MS\ Word} документ ќе биде прикажан како задебелен, курзив, со линкови, итн.
\hypertarget{ux43fux43bux435ux442ux435ux45aux435-ux43dux430-ux442ux435ux43aux441ux442-ux43aux43eux434-ux438-ux440ux435ux437ux443ux43bux442ux430ux442ux438-ux441ux43e-knitr}{%
\section{\texorpdfstring{Плетење на текст, код, и резултати со \texttt{knitr}}{Плетење на текст, код, и резултати со knitr}}\label{ux43fux43bux435ux442ux435ux45aux435-ux43dux430-ux442ux435ux43aux441ux442-ux43aux43eux434-ux438-ux440ux435ux437ux443ux43bux442ux430ux442ux438-ux441ux43e-knitr}}
Досега видовме како можеме лесно да маркираме обичен текст кој ќе биде процесиран во убаво форматиран документ. Она што ни недостасува е комбинирање (плетење) на ваквиот текстот со програмски код и резултатите од тој код. \texttt{rmarkdown} го прави овој чекор супер едноставен. Се што е неопходно е да додадеме парче код кое почнува со нотацијата \texttt{\textasciigrave{}\textasciigrave{}\textasciigrave{}\{r\}} и завршува со нотацијата \texttt{\textasciigrave{}\textasciigrave{}\textasciigrave{}}. Тогаш \texttt{R} и пакетот \href{https://www.rdocumentation.org/packages/knitr/versions/1.30}{\texttt{knitr}} \citep{knitr1, knitr2, knitr3} ќе се обидат да го интерпретираат и извршат сиот текст во ова парче како \texttt{R} код или коментари што почнуваат со \texttt{\#}. Доколку извршувањето на тој код резултира со табела или график, \texttt{knitr} ќе го прикаже тој елемент веднаш под извршениот код.
Ова е далеку полесно со пример:
\begin{figure}
\centering
\includegraphics{www/rmd.png}
\caption{Пример за еден едноставен Rmd документ што прикажува текст, код, и резултати}
\end{figure}
Откако ќе го сплетеме овој документ, добиваме:
\begin{figure}
\centering
\includegraphics{www/rmd-rendered.png}
\caption{HTML документ креиран со плетењето на горниот Rmd код}
\end{figure}
Ова навистина само ја допира површината на тоа што е можно да се направи со алатките како \texttt{rmarkdown} и \texttt{knitr}. Имајќи во предвид дека крајните документи се \texttt{HTML}, \texttt{LaTex}, или \texttt{MS\ Word}, голем дел од богатсвото на можности на овие далеку поопширни \texttt{markup} системи ќе ви бидат достапни кога пишувате анализи во \texttt{rmarkdown}. Така да, ако сакате да вклучите лого од вашата организација, посебен фонт, специјално форматирње на маргини, пагинација, итн, сето тоа ќе можете тоа да го направите со стандардни методи достапни во \texttt{HTML} или \texttt{LaTeX}.
\hypertarget{ux438ux437ux432ux435ux448ux442ux430ux438-ux441ux43e-ux43fux430ux440ux430ux43cux435ux442ux440ux438}{%
\section{Извештаи со параметри}\label{ux438ux437ux432ux435ux448ux442ux430ux438-ux441ux43e-ux43fux430ux440ux430ux43cux435ux442ux440ux438}}
Она што за нас е посебно корисно и интересно, е користењето на оваа платформа за писмено програмирање за пишување на \href{https://rmarkdown.rstudio.com/developer_parameterized_reports.html\%23parameter_types\%2F}{параметризирани извештаи}. Што значи ова? Па доколку имате некоj стандарден сет на анализи кои треба да ги повторите за сите градови во Македонија, можете да го извршите вашиот \texttt{Rmd} извештај со параметар за тоа кој град треба да биде обработен. Во самиот изворен код на извештајот, дефинирате \href{https://yaml.org/spec/1.2/spec.html}{\texttt{yaml}} преамбула налик на следната:
\begin{verbatim}
---
title: Мој Извештај
output: html_document
params:
grad: Tetovo
---
\end{verbatim}
Ова креира листа на параметри со името \texttt{params} која е достапна во \texttt{R} средината за време на извршувањето на документот, чијшто елементи може да ги употребите на следниот начин:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{params}\SpecialCharTok{$}\NormalTok{grad}
\end{Highlighting}
\end{Shaded}
Доколку имаме некоја функција во нашиот извештај која се извршува пред правење на некој график за одреден град:
\begin{Shaded}
\begin{Highlighting}[]
\FunctionTok{library}\NormalTok{(dplyr)}
\NormalTok{filtriraj\_gradovi }\OtherTok{\textless{}{-}} \ControlFlowTok{function}\NormalTok{(podatoci, potreben\_grad) \{}
\NormalTok{ podatoci }\SpecialCharTok{\%\textgreater{}\%}\NormalTok{ dplyr}\SpecialCharTok{::}\FunctionTok{filter}\NormalTok{(grad }\SpecialCharTok{==}\NormalTok{ potreben\_grad)}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
Тогаш можете параметарот даден во преамбулата да го искористите при повикувањето на фунцкијата, и сите натамошни резултати ќе бидат посветени на градот што сме го пратиле како параметар:
\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{\# претходен код и текст}
\FunctionTok{filtriraj\_gradovi}\NormalTok{(}\AttributeTok{podatoci =}\NormalTok{ moi\_podatoci, }\AttributeTok{potreben\_grad =}\NormalTok{ params}\SpecialCharTok{$}\NormalTok{grad)}
\CommentTok{\# натамошен код и текст}
\end{Highlighting}
\end{Shaded}
За да ги направиме сите извештаи побрзо, во можеме да го повикуваме извршувањето во \texttt{R} конзола:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{rmarkdown}\SpecialCharTok{::}\FunctionTok{render}\NormalTok{(}\AttributeTok{input =} \StringTok{"mojizvestaj.Rmd"}\NormalTok{, }\AttributeTok{params =} \FunctionTok{list}\NormalTok{(}\StringTok{"Tetovo"}\NormalTok{))}
\end{Highlighting}
\end{Shaded}
Оттука, можеме дури и да напишеме \texttt{for} циклус со кој што ќе ги процесираме сите градови наеднаш и ќе генерираме посебен \texttt{HTML}, \texttt{PDF} или \texttt{MS\ Word} документ се секој град:
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{gradovi }\OtherTok{\textless{}{-}} \FunctionTok{c}\NormalTok{(}\StringTok{"Tetovo"}\NormalTok{, }\StringTok{"Gostivar"}\NormalTok{, }\StringTok{"Debar"}\NormalTok{, }\StringTok{"Berovo"}\NormalTok{, }\StringTok{"Dojran"}\NormalTok{) }\CommentTok{\# ...}
\ControlFlowTok{for}\NormalTok{ ( i }\ControlFlowTok{in}\NormalTok{ gradovi) \{}
\FunctionTok{message}\NormalTok{(}\StringTok{"Подготвувам извештај за: "}\NormalTok{, i)}
\NormalTok{ rmarkdown}\SpecialCharTok{::}\FunctionTok{render}\NormalTok{(}\AttributeTok{input =} \StringTok{"pateka/do/mojizvestaj.Rmd"}\NormalTok{, }\AttributeTok{params =} \FunctionTok{list}\NormalTok{(i))}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
Како оваа стратегија ја подобрува повторливоста на нашите анализи? Доколку немаме извештаи со параметри можеме да замислиме две стратегии. Првата, имаме еден главен \texttt{izvestaj.Rmd} којшто никогаш не го менуваме и правиме копии за секој град, така што набрзо нашата работна средина станува невозможна за менаџирање на долг рок:
\begin{verbatim}
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
\end{verbatim}
Втората, имаме еден \texttt{izvestaj.Rmd} којшто го менуваме директно и секогаш мора да го отвориме, промениме, и извршиме рачно. Така да кога ќе стигнат новите податоци следниот месец имаме 2-3 часа работа да го промениме градот во функцијата горе триесетина пати.
Дури и да го имате потребното време за вакви активности, очигледно е дека со овие опции е далеку полесно да направите грешка отколку со извештајот со параметри, којшто го пишувате еднаш и можете да го користите секогаш кога ќе ви треба без да го менувате изворниот код. Доколку треба да се измени или подобри извештајот, тоа се прави со промена на само еден документ, не треба да се сетите дека \texttt{kopje-izvestaj-juni-specijalen-so-logo.Rmd} треба да се промени засебно бидејќи има нешто специфично.
\hypertarget{ux441ux43bux435ux434ux43dux438-ux447ux435ux43aux43eux440ux438}{%
\section{Следни чекори}\label{ux441ux43bux435ux434ux43dux438-ux447ux435ux43aux43eux440ux438}}
Околината на \texttt{rmarkdown} и \texttt{knitr} е особено богата со алатки за посебни намени што навистина можат да придонесат кон поголема транспарентност и повторливост на вашите анализи и генерално кон поголема продуктивност во вашата работа. Подолу наведуваме само неколку од овие алатки:
\begin{itemize}
\tightlist
\item
креирање презентации (на пример: \href{https://rmarkdown.rstudio.com/lesson-11.html}{тука} или \href{https://bookdown.org/yihui/rmarkdown/xaringan.html}{тука})
\item
креирање \href{https://rmarkdown.rstudio.com/lesson-14.html}{\emph{интерактивни} \texttt{Rmd}} документи што користат \href{https://shiny.rstudio.com/}{\texttt{Shiny}} \citep{R-shiny} во позадина
\item
креирање стилизирани HTML документи со \href{https://prettydoc.statr.me/}{\texttt{prettydoc}}
\item
креирање на книги со \href{https://bookdown.org/}{\texttt{bookdown}} (како овој текст)
\item
креирање на едноставни \href{https://rmarkdown.rstudio.com/lesson-13.html}{\texttt{rmarkdown} вебсајти} со \texttt{rmarkdown::render\_site}
\item
креирање на дашбоарди со \href{https://rmarkdown.rstudio.com/lesson-12.html}{\texttt{flexdashboard}}
\end{itemize}
\hypertarget{ux440ux435ux437ux438ux43cux435-3}{%
\section{Резиме}\label{ux440ux435ux437ux438ux43cux435-3}}