-
Notifications
You must be signed in to change notification settings - Fork 0
/
IntroToR_UKR.Rmd
1072 lines (834 loc) · 43.3 KB
/
IntroToR_UKR.Rmd
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
---
title: "R - база! введення в R для початківців"
output:
word_document: default
pdf_document: default
editor_options:
markdown:
wrap: 72
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(eval = FALSE)
```
#####Структура воркшопу
* Навігація по Rstudio
* Блок 1
+ Базові правила R скрипта
+ Синтаксис
+ Класси даних
+ Структури даних
* Q&A 5 хв
* Блок 2
+ Цикли та галуження
+ Apply
+ Написання функцій
+ Зберігти і завантажити дані
+ Дослідження даних
* Q&A 5 хв
* Блок 3
+ Візуалізація
+ Tidyverse + (короткий Q&A, під час інсталяції)
+ Як вивчати R?
* Посилання
* Q&A
> Зверніть увагу: якщо ви загубилися у файлі семінару, натисніть "Outline" (у правій верхній частині цього вікна) та виберіть тему, на якій ми зараз. **АБО** зауважте, на якому рядку зараз знаходиться курсор лектора (зліва від цього вікна в сірому стовпчику) і прокрутіть вниз до цього номера рядка.
###Базові правила R скрипта
> Щоб запустити блок коду, клацніть на блок і натисніть «Ctrl+Enter» або клацніть маленький зелений прямокутник праворуч в кутку блоку.
>Щоб запустити один рядок коду, клацніть рядок і натисніть "Ctrl+Enter" або натисніть "Run" - "Run Selected Line(s)" праворуч від ціого вікна.
Рядки, що пояснюють код (коментарі), повинні починатися з #. Інакше виникне помилка.
Так само можна позначати рядки, в яких ви хочете, щоб код не виконувався.
```{r}
#Comments are not executed.
Comments without "#" sign will give error.
```
Правильно написана команда, як виклик функції, не викликатиме помилки.
```{r}
#print() function prints its arguments in console.
print('Code without syntaxis mistakes and correct arguments will not give an error.')
```
Давайте дослідимо поняття функції, адже ми будемо їх використовувати постійно.
> Функція — це послідовність програмних інструкцій, яка виконує конкретне завдання.
Функції визкликаються так **назва_функції(аргументи)**.
Деякі функції не приймають аргументи, інші приймають. Кількість аргументів
закодована у функції. Деякі функції виводять результат, інші виконують задачу без виводу
текстового результату.
```{r}
#Function getwd() prints the current working directory. It does not take arguments.
getwd()
```
```{r}
#Function setwd() sets as a working directory given as an argument. It does not print anything. Note, that path to directory should be taken in quotes.
setwd("./") # "./" це традиційне позначення поточної робочої директорії
```
Щоб дізнатися, що робить функція запустіть **?назва_функції**
```{r}
?print
```
Аргументи можуть бути спеціальними (custom) та за замовчуванням (default). Спеціальні аргументи мають вказуватись завжди під час виклику функції. Аргументи за замовчуванням, якщо їм не дано нове значення при виклику, завжди матиме значення, попередньо встановлене розробниками.
```{r}
#The call of function, that requires argument, without argument will give an error.
print()
```
```{r}
print("This string is an 'x' argument in function print()")
```
```{r}
#Argument "quote" is set to "FALSE" by default, but we can change it to "TRUE".
print(factor(5),quote = FALSE) # Ми обговорюватимемо factor() функцію пізніше
print(factor(5),quote = TRUE)
```
Функції упаковані в пакети (packages). Один пакет може складатися з кількох функцій. Є пакети за замовчуванням, які завантажуються автоматично в сеанс. Щоб перевірити, які пакети зараз завантажено в сеанс...
```{r}
#Print version information about R, the OS and attached or loaded packages.
sessionInfo()
```
До речі, виклик функцій в R є чутливим до регістру. Назва функції, написана не відповідним регістром не буде знайдена.
```{r}
sessioninfo() #upper\lower
```
> Підказка, щоб стерти текст з консолі, натисніть Ctrl+l.
Існують тисячі інших пакетів, які можна встановити та завантажити до сеансу. Наприклад, для воркшопу нам знадобляться пакети «ggplot2», «dplyr», і "readr". Перевірте, чи встановлено у вас ці пакети чи ні. Якщо так, в який каталог?
```{r}
#Finds the full file names of files in packages etc.
system.file(package='ggplot2')
system.file(package='dplyr')
system.file(package='readr')
```
Якщо таких пакетів немає, давайте їх встановимо.
#Skip till Q&A
```{r}
#Download and install packages from CRAN-like repositories or from local files. CRAN is a network of ftp and web servers around the world that store identical, up-to-date, versions of code and documentation for R. Apart of CRAN, there is a popular repository Bioconductor.
install.packages("ggplot2")
install.packages("dplyr")
install.packages("readr")
```
> Встановлення може тривати кілька хвилин.
Тепер ці два пакети збережено на вашому комп’ютері. Щоб користуватися їми, треба ці пакети завантаженти в сеанс.
#Skip till Q&A
```{r}
#library() load and attach add-on packages.
library("ggplot2")
library("dplyr")
library("readr")
```
Зауважте, деякі функції мають однакові назви в різних пакетах. Якщо викликати просто **назва_функції()**, це може спричинити плутанину, якого пакета функцію було використано. Це особливо стосується пакетів для аналізу біологічних даних (наприклад plot()). Щоб вказати, яку функцію викликати, використовуйте **назва_пакету :: назва_функції()**
```{r}
#The package "base" has function "mean" which returns arithmetic mean.
base::mean(5)
```
> Якщо ви знаєте, що функції в завантажених пакетах не збігаються, використовувати **::** не потрібно.
###Синтаксис
Щоб спростити операції над даними, даним присвоюється змінна. Як ви кладете м’яч у кошик, так само ви додаєте дані до змінної.
>Змінна — це абстрактна комірка пам'яті комп'ютера в парі з асоційованим символічним ім'ям, яка містить деякі дані.
Щоб призначити дані змінній, використовуйте знак **<-**. Окрім даних, можна викликати функцію, яка автоматично передасть результат у змінну.
```{r}
# "Put" number in x.
x<-5
# writing just variable in script or console we can see its content.
x
```
```{r}
# Addition function "+" passes output to variable y.
y<-1+3
y
```
Будьте обережні, якщо значення змінної змінюється, попереднє значення стирається,але вихід функцій та значення змінних, викликаних до зміни, залишається таким самим.
Щоб уникнути такої ситуації, обов’язково запустіть функцію ще раз.
```{r}
a<-x+y
# change "y" value from 4 to 7
y<-7
# "a" value corresponds to 5+4, but not 5+7
a
# run code again
a<-x+y
# now "a" is correct
a
```
Існують правила щодо вибору імені змінної.
* Уникайте імена, що починаються з цифри.
* Майте на увазі, що R чутливий до регістру.
* Уникайте назв функцій у R.
* Зробіть свої назви зрозумілими і не надто довгими.
* Дотримуйтеся однакового стилю назв змінних впродовж всього коду.
```{r}
#Variables can't start with number
1a<-8 #not allowed
a1<-8 #better
#Variables are case-sensitive
# A1 not the same as a1
print(A1)
#Do not use function names. "if" is part of control-flow constructs. Discussed later.
if<-3
# Too complex and hard to understand name.
thisismyfirstsubtraction<-4-5
my_1st_subtraction<-4-5
```
###Класи даних
Тут ми зосередимося на трьох классах даних.
*Numeric (числовий)
```{r}
# Function class prints the names of classes an object inherits from.
class(5)
class(0.5)
```
*Character (строка)
```{r}
# Any symbol taken in quotes considered a string.
class("5")
class("Hello")
```
*Logical (логічний)
```{r}
class(TRUE) #TRUE is the same as T
class(FALSE) #FALSE is the same as F
```
Зверніть увагу, є об'єкти "NaN" і "NA". Значення "NaN" у R "NOT a NUMBER", це в основному будь-які числові обчислення за невизначеним результат.
```{r}
0/0
```
```{r}
class(NaN)
```
Значення NA в R означає "NOT AVAILABLE" і використовується, коли значення загублене.
```{r}
class(NA)
```
Об'єкти "NaN" і "NA" можна ідентифікувати за допомогою функції **is.na()**, яка повертає вектор із логічними значеннями.
```{r}
# c() function creates a vector out of elements. Discussed later.
is.na(c(1,2,NaN,NA))
```
###Структури даних
Зазвичай біологічні дані більш складні, ніж окремі числа, строки тощо. Це значення, організовані в набори даних або структури даних.Існують одновимірні структури даних, такі як вектор, фактор і список, і двовимірні як матриця та дата фрейм даних.
> Існують різні способи створювати структури даних. Ми продемонструємо декілька з них.
```{r}
# c() function creates a vector out of elements.
vector1<-c(11,8,96,23)
vector1
```
```{r}
# factor() creates a factor object out of ordered vector.
factor1<-factor(c(3,3,3,5,5,6,6))
factor1
```
```{r}
# list() function assembles input objects (any) into list.
list1<-list(c(1,2),c(3,4))
list1
```
```{r}
# matrix() function creates matrix out of vector of length nrow*ncol (number of rows and columns)
matrix1<-matrix(c(4,15,0,47,101,62), nrow = 2, ncol = 3)
matrix1
```
```{r}
# data.frame() function creates data frame from input object (vectors/matrix/list).
#because we did not set the names of columns, R creatеs them by default.
df1<-data.frame(c(0,0.3,0.96,1),c(2,-6,0.5,14),stringsAsFactors=FALSE)
df1
```
**То навіщо нам потрібні різні структури даних?**
* Перш за все, кожна зі структур даних має унікальні властивості, які роблять їх легшими для
використання в тому чи іншому типі аналізу.
* По-друге, деякі обчислення виконуються швидше із тими чи іншими структурами даних.
* Крім того, іноді функції потребують вхідні дані певної структури.
Вектор, фактор і матриця беруть вхідні дані з одного класу. Якщо їм надаються елементи з різних класів, вони будуть перетворені в однаковий автоматично.
```{r}
# vector with elements of different classes
c(1,"1",TRUE)
```
```{r}
#factor with elements of different classes
factor(1,"1",TRUE)
```
```{r}
#Another way to create a matrix is to specify only one dimension parameter (ncol) and give the names to rows and columns at once. Note, that in argument "dimnames" the list is created, where first vector is row names and second is column names.
matrix2<-matrix(c(1,"1",TRUE,1,"1",TRUE),ncol=2,dimnames = list(c("row1","row2","row3"),c("col1","col2")))
matrix2
```
Але можна задавати класс елементів.
```{r}
#change it to numeric
as.numeric(c(0,"1"))
```
```{r}
#change to character
as.character(c(0,"1"))
```
Навпаки, список і дата фрейм можуть приймати елементи різних класів.
```{r}
#Another way to create a data frame, is to simultaneously give column names to each vector (col1, col2).
df2<-data.frame(col1=c(FALSE,TRUE),col2=c("3",4))
df2
```
```{r}
#Lists can store not only elements and vectors, but also other data structures as matrix and data frame, and even lists. List in a list is called "nested list".
list2<-list("A"=matrix1,"B"=df2)
list2
```
Можна швидко оцінити розміри кожного об'єкта, але функції для 1-вимірних і 2-вимірних структур даних
різні.
```{r}
# Function length() gets or sets the length of vectors (including lists) and factors.Here we use print() only to show output of each line at once.
print(length(vector1))
print(length(factor1))
print(length(list1))
```
```{r}
# Function dim() retrieves or sets the dimension of an object.
print(dim(matrix1))
print(dim(df1))
# nrow() and ncol() return the number of rows or columns present in object.
cat(nrow(matrix1),ncol(matrix1)) # cat() allows to print several objects together (print() prints only one).
```
Крім перевірки даних на око, нам зазвичай потрібно їх модифікувати перед аналізом. Давайте розглянемо вкрай необхідні операції.
Часто імена підмножин даних (як імена стовпців і рядків в матриці/дата фреймі або елементи в списку) занадто довгі чи не зрозумілі, або вони відсутні.
> Зверніть увагу, вектори не мають імен елементів.
```{r}
# Matrix and data frame use the same functions.
print(matrix1)
colnames(matrix1) <- c("experiment_1","experiment_2","experiment_3")
rownames(matrix1) <- c("object_1","object_2")
print(matrix1)
```
>Зауважте, дата фрейми не допускають дублювання імен рядків і стовпців, хоча матриця та список (лише імена) допускають.
```{r}
# List is 1-dimensional, so it does not have columns or rows.
names(list1)
names(list1)<-c("vector_1","vector_2")
list1
```
Які модифікації можна виконати з даними? Як додавати або видаляти стовпці чи як додати цілий набір даних до існуючого?
Кожен елемент у даних має свій порядковий номер (індекс). Індекс дозволяє витягти один або кілька конкретних елементів. Індекс завжди береться в **[]**.
> Зверніть увагу, тут ми показуємо приклади на векторі та дата фреймі, щоб заощадити час.
Для інших структур даних знайдіть приклади в Інтернеті.
```{r}
# Get second element in vector.
vector1[2]
```
```{r}
# Get second and third elements in vector.
vector1[2:4]
```
```{r}
# Get first and third element in vector.
vector1[c(1,3)]
```
```{r}
# Instead of writing all needed index, subtract unneeded elements
vector1[-2] # "-" minus before index makes this element to drop from vector.
```
```{r}
# Selected element or set of element's can be substituted.
vector1[2]<-3
vector1
```
В 1-вимірних структурах даних це один індекс, а в 2-вимірному - два (по одному для рядків і стовпців).
Зріз дата фрейму подібний до матриці, але має додаткові функції. Знак **$** викликає стовпець за його іменем, замість того, щоб брати ім'я в прямокутні дужки. Зріз списку подібний до дата фрейму, але за допомогою подвійних дужок **[[]]**.
```{r}
# Select one element
df2[1,2]
```
```{r}
# Select whole row
df2[1,]
```
```{r}
# select whole column
df2[,1]
```
```{r}
# Use names instead of indexes
df2[,c("col1", "col2")]
```
```{r}
# Substitution
df2[1,"col1"]<- -10
```
```{r}
# Get column with $column_name
df2$col1
```
```{r}
# Get second element (in second row) of the column.
df2$col1[2]
```
У великих наборах даних важко вибрати цікаві елементи шляхом перераховування індексів. Натомість ми можемо вибрати елементи за умовою.
Існує багато можливих комбінацій умов. Основними є:
* > "більше ніж" < "менше ніж"
* == "дорівнює"
* >= "більше або дорівнює" <= "менше або дорівнює"
* | "або"
* & "і"
* %in%, якщо елемент або підрядок присутні в списку або рядку
```{r}
# Condition is a logical operation, which outputs logical data. > "bigger then"
vector1>10
```
```{r}
# Function which() selects elements with value="TRUE" and outputs its index.
which(vector1>10)
```
```{r}
# To select element, put condition as index.
vector1[which(vector1>10)]
```
Для дата фреймів умова встановлюється схожим чином.
```{r}
#Select rows in second column with negative elements and more then 10.
df1[which(df1[,2]<0 & df1[,2]>10),2] # no output, because there is no such number.
```
```{r}
df1[which(df1[,2]<0 | df1[,2]>10),2]
```
І умови можуть стосуватися не тільки цифр, але й інших класів теж.
```{r}
# Convert all numbers in characters.
# sapply() allows to use one function on all elements of data frame. Discussed later.
df3<-sapply(df1, as.character)
```
```{r}
# Select elements with "0" substring.
df3[which("0" %in% df3[,1]),]
```
```{r}
# Select ALL elements with "0" substring.
# grep() search for matches to argument pattern within each element of a character vector.
df3[grep("0",df3[,1]),]
```
Трапляється, що нам потрібно додати деякі дані до наборів даних.
```{r}
#Combine rows of two data frames.
rbind(df2,df2[1,])
```
```{r}
#Combine columns of two data frames.
cbind(df2,df2[,1])
```
```{r}
#Merge two data frames by common columns.
merge(df2,df2,by="col2")
#The different arguments to merge() allow you to perform natural joins i.e. inner join, left join etc.
```
#Instaling packages
####Q&A
###Цикли та галуження
Виконання повторюваних перетворень даних або обчислень даних можна оптимізувати за допомогою циклів.
>Коли ви створюєте цикл, R виконує інструкції в циклі задану кількість разів або доки виконується задана умова.
Існує два популярних типи циклів *while* і *for*. Їх загальний синтаксис **функція_циклу(умова){код}**.
>Цикл for використовується коли кількість ітерацій вже відома. Цикл while використовується, коли кількість ітерацій наперед невідома.
Наприклад, замість написання 20 рядків коду...
```{r}
i<-1
print(i)
i<-i+1
print(i)
i<-i+1
#...17 more
```
...цикл скорочує код до 5 рядків...
```{r}
i<-0
while (i<20){
i<-i+1
print(i)
}
```
...або цикл *for* до 3 рядків.
```{r}
for (i in 0:19){
print(i+1)
}
```
Коли ми переглядаємо реальні дані, ми можемо захотіти обробити різні значення різними способами. Дані можна вибрати за однією умовою **if (умова) {код}** або двома **if (умова){код} else {код}** чи більше **if (умова){код} else if (умова){код} else if (){}...**
```{r}
#Indicate add and even numbers.
# paste() concatenate vectors after converting to character.
for (i in 1:20){
if (i%%2==0){
print(paste(i," is even"))
} else {
print(paste(i, "is odd"))
}
}
```
Функції if/else також корисні для завершення циклів, якщо це необхідно.*break*
зупиняє цикл, *next* пропускає код під ним на одну ітерацію.
```{r}
#Select numbers under 10.
#runif() return uniformly distributed random numbers.
k<-1
for (i in runif(10, min=0, max=100)){
if (i<10){
print(i)
next
} else if (k==10){
print("no number under 10")
break
}
k<-k+1
}
```
###Apply
R має функції, які застосовують (**apply**) одну функцію до даних. Вони корисні для запису циклу в один рядок і виконуються швидше.
>Ми розглянемо чотири такі функції *apply*, *tapply*,
*sapply*, *lapply*. Вони відрізняються структурою вхідних і вихідних даних.
```{r}
# apply(data,dim,function)
#Returns a vector or array or list of values obtained by applying a function to margins of an array or matrix.
apply(matrix2,1,sum)
```
```{r}
# tapply(value_vector,group_vector,function)
#Apply a function to each cell of a ragged array, that is to each group.
tapply(runif(10, min=0, max=100),c("group1","group1","group2","group3","group4","group4","group4","group5","group5","group5"),sum)
```
```{r}
# sapply(value_list,function)
# Returns vector or matrix.
#If you want to past a custom function, use syntax: function(input_variable){code}
sapply(0:4, function(a) {a + 1})
```
```{r}
# lapply(value_list,function)
# Returns list.
lapply(0:4, function(a) {a + 1})
```
###Написання функцій
Як було показано, сімейство функцій *apply* дозволяє вставляти власну функцію для застосування до даних. Якщо функція займає більше, ніж один рядок, краще написати її раніше та зберегти у змінній (спеціальне ім'я функції). Загальний синтаксис для написання функції такий **назва_функції<-function(аргументи){}**.
Так само, як функції, завантажені з пакетів, власні функції можуть не брати аргументів, брати 1 або більше аргументів, мати аргументи за замовчуванням, **return** вихід або ні.
```{r}
#without arguments
f1 <- function() {
return('hello')
}
f1()
```
```{r}
# call function
f1()
```
```{r}
#with argument
f2 <- function(name) {
x <- paste("hello", name)
return(x)
}
```
```{r}
#test
f2('Ivanka')
out2<-f2('Ivanka')
```
```{r}
#with default argument
f3<-function(x,y=10){
return(x*y)
}
```
```{r}
#pass one argument
f3(5)
```
```{r}
#change second argument
f3(5,4)
```
Еліпси дозволяють вказати аргументи, яких немає в списку аргументів функції, але може використовуватися в блоці коду.
```{r}
#with ellipses.
f4 <- function(x, ...) {
a<-f3(x, ...)
print(a)
}
```
```{r}
#test
f4(x=1,y=3)
```
**Вітаємо!** Тепер ви знаєте необхідний мінімум, щоб мати змогу читати скрипт R. Давайте підемо далі і пограємо із зразком реальних даних.
```{r}
#Loads specified data sets, or list the available data sets.
data()
```
```{r}
#Load several data sets for later use.
data(mtcars)
data(pressure)
data(BOD)
```
###Зберегти і завантажити данні
Зазвичай дані, які потрібно переглянути й проаналізувати, зберігаються в текстовому файлі з розширеннями .txt, .csv, .tsv, .xlsx тощо. Розширення можуть вказувати на
роздільник між стовпцями у файлі (наприклад, кома є роздільником у .csv і
tab у .tsv).
Існують функції, призначені для читання таких файлів в R. Але спочатку збережемо дата фрейм **mtcars** у файли з різним розширенням.
> Зауважте, файли .xlsx читаються окремими пакетами, напр."readxl", який ми не розглядатимемо на семінарі.
```{r}
#write.table prints its required argument x to a file.
# sep="\t" indicates tab separator.
write.table(mtcars, "mtcars.tsv", row.names=FALSE, sep="\t")
```
```{r}
# write.csv() by default sets separator as comma (,) and dot (.) as decimal point.
write.csv(mtcars, "mtcars.csv", row.names=FALSE)
```
Тепер файли *mtcars.tsv* і *mtcars.csv* мають з’явитися у вашому робочому каталозі. Ми можемо прочитати файл і зберегти його вміст у змінній.
```{r}
#read file.
read.table("mtcars.tsv", sep="\t",header=TRUE)
```
```{r}
# put file content in variable.
mtcars_fromfile <- read.csv("mtcars.csv", stringsAsFactors=FALSE)
```
###Дослідження даних
Рекомендується досліджувати набір даних перед аналізом. Це дає вам розуміти дані та перевірити, чи щось з ними не так. Як приклад набору даних ми будемо використовувати *mtcars*. Запустіть наступний код і подивіться на праве нижнє вікно, щоб дізнатися більше про набір даних.
```{r}
?mtcars
```
Перевірте розмір набору даних.
```{r}
# output: number of rows, number of columns
dim(mtcars)
```
Для першого погляду на дані достатньо побачити назви стовпців і перші/останні рядки.
```{r}
# second argument specifies number of rows you want to display (default is 5 rows).
head(mtcars,2)
```
```{r}
tail(mtcars)
```
Крім того, компактно відобразіть внутрішню структуру об’єкта R.
```{r}
# output: column names: data class: first 10 values.
str(mtcars)
```
А якщо ви хочете досліджувати дані вручну, відображайте їх у повному розмірі.
```{r}
View(mtcars)
```
Ми хотіли б знати, чи якісь значення відсутні в даних або дублюються.
Обидва випадки можуть спричинити оманливі результати після аналізу.
```{r}
# check if there's any NA or NaN values
is.na(mtcars)
```
```{r}
# check if there blank values (no character)
mtcars[mtcars==""]
```
```{r}
#check if there duplicated rows
# duplicated() determines which elements of a vector or data frame are duplicates.
sum(duplicated(mtcars))
```
Якщо ви очікуєте, що будь-який стовпець матиме категоричні значення, перевірте, чи всі категорії присутні й названі правильно, а також кількість рядків, що містять кожну з категорій.
```{r}
# unique() removes duplicated elements/rows.
unique(mtcars$cyl)
```
```{r}
# table() builds a contingency table of the counts.
table(mtcars$cyl)
```
Деякі стовпці можуть бути поєднані між собою як підкатегорії (наприклад,
стовпці "group", "subgroup", "sample_name") або їх значення корелюють
(наприклад, стовпці "num_of_mitochondria", "num_of_ATP"). Щоб перевірити чи
кореляція не порушена, ми можемо сортувати набір даних за стовпцями.
```{r}
#order() returns a rearranged data set with into ascending or descending order.
head(mtcars[order(mtcars$cyl),],10)
```
Ви можете зробити швидку статистичну оцінку ваших даних. Можна перевірити кожен параметр окремо (середнє, мінімальне, максимальне тощо) або всі разом.
```{r}
print(paste("minimum value ",min(mtcars$mpg)))
print(paste("maximum value ",max(mtcars$mpg)))
print(paste("mean ",mean(mtcars$mpg)))
```
```{r}
summary(mtcars)
```
Ще один ефективний спосіб швидко зрозуміти дані – візуалізувати їх. Однак візуалізація також відіграє важливу роль у відображенні результатів аналізу у звітах чи статтях.
####Q&A
###Візуалізація
R дозволяє робити прості візуалізації. Але найпопулярнішим пакетом для візуалізації біологічних даних є *ggplot2*.
>*ggplot2* допомагає створювати складні графіки. Він надає гнучкіший програмний інтерфейс для контролю даних, які відображаються, того, як вони відображаються та загальних візуальних властивостей.
Тут ми швидко розглянемо попередньо завантажені дані за базовими графіками R і *ggplot2*, щоб побачити різницю та приклади синтаксису.
>Візуалізація — це велика тема, і багато частин не розглядаються на вокркшопі. Дивіться також лекцію GENOMICS UA https://www.youtube.com/watch?v=FC-CiVgkWYA.
Існують такі типи простих графіків, як *діаграма розсіювання, лінійна діаграма, стовпчаста діаграма, гістограма, коробчаста діаграма, крива*, хітмап (пропущена).
Однією з базових функцій є plot.
```{r}
# Scatter plot shows relationship between two sets of numbers.
plot(mtcars$wt, mtcars$mpg)
```
```{r}
# Line plot are useful when comparing multiple variables.
plot(pressure$temperature, pressure$pressure, type = "l") # type="l" specifies that line should be plotted
# add points to see all values.
points(pressure$temperature, pressure$pressure, col="red")
```
Щоб побудувати кілька графіків разом (subplots), використовуйте наступний синтаксис.
```{r}
# par() can be used to set or query graphical parameters.
# mfrow - vector of the form c(number of rows, columns).
par(mfrow = c(1, 2))
plot(ToothGrowth$supp, ToothGrowth$len)
plot(pressure$temperature, pressure$pressure, type = "l")
#dev.off()
#dev.off shuts down the specified (by default the current) graphic. If not written, new plots will overdraw the old. Here we commented previous line to display graphics.
```
Щоб зберегти *базові* графіки як файл, додайте **extention_name_function("directory/name_of_plot.extention")**
```{r}
jpeg('./rplot.jpg') #also png, pdf etc.
plot(mtcars$wt, mtcars$mpg)
dev.off()
# rplot.jpg should appear in your working directory.
```
Синтаксис *ggplot2* відрізняється від базових графіків. Якщо базові графіки зазвичай визиваються як **plot_function(data, style_arguments)**, то ggplots є складнішими:
**ggplot(data = <DATA>, mapping = aes(<MAPPINGS>)) + <GEOM_FUNCTION>()**
* естетична (aes) функція бере змінні, які потрібно побудувати, і визначає, як їх представити на графіку, наприклад, у вигляді позицій x/y і таких характеристик, як розмір, форма, колір тощо.
>На початку воркшопу ми вже встановили та завантажили пакет *ggplot2*.
```{r}
# blank plot
ggplot(mtcars, aes(x = wt, y = mpg))
```
Незважаючи на те, що x і y вказані, графік є пустим. Це тому, що ggplot не припускає, що ви мали на увазі точкову діаграму або лінійну діаграму тощо, яку потрібно намалювати (без «geoms»).
* додати ‘geoms’ – графічне представлення даних на графіку (точки, лінії, смуги тощо). Може бути кілька «geoms» у поєднанні з «+» таким чином, щоб відобразити кілька графіків в одному.
+ *geom_point()* для діаграм розсіювання
+ *geom_line()* для ліній тренду
+ *geom_col()* для стовпчастої діаграми
+ *geom_histogram()* для гістограм
+ *geom_boxplot()* для бокс плот
+ *stat_function()* для кривої
```{r}
#Run whole chank.
#scatter plot
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(aes(colour = mpg)) +
scale_colour_gradient(low = "yellow", high = "red", na.value = NA)
#scale_colour_gradient() gives color scale to chosen variable
```
```{r}
#line
ggplot(pressure, aes(x = temperature, y = pressure)) + geom_line() + geom_point()
```
```{r}
#bar plot
ggplot(BOD, aes(x = Time, y = demand)) + geom_col()
```
```{r}
#histogram
ggplot(mtcars, aes(x = mpg)) + geom_histogram(binwidth = 4)
```
```{r}
#box plot
ggplot(ToothGrowth, aes(x = supp, y = len)) + geom_boxplot() #one variable
ggplot(ToothGrowth, aes(x = interaction(supp, dose), y = len)) + geom_boxplot() #several variables
```
```{r}
#curve
myfun <- function(xvar) { 1 / (1 + exp(-xvar + 10))}
ggplot(data.frame(x = c(0, 20)), aes(x = x)) + stat_function(fun = myfun, geom = "line")
```
**Красиво, чи не так!?**
> Є можливість змінювати назви осей, назву, розмір графіка, колір, обертати. Але ми пропустимо ці нюанси. Щоб дізнатися більше, відвідайте https://r-graph-gallery.com/.
Хоча ви можете використовувати par(), щоб зберегти ggplot як базовий графік, існує спеціальна функція з пакету *ggplot2*.
```{r}
ggplot(mtcars, aes(wt, mpg)) + geom_point()
# Save the plot to a pdf
ggsave("myplot.pdf")
```
###Tidyverse
##Small Q&A, during installation
```{r}
install.packages("tidyverse")
library(tidyverse)
```
Зверніть увагу: якщо у вас виникли проблеми з інсталяцією *tidyverse*, блоки коду, які вимагають функцій поза завантаженими на початку семінару, позначені *#!*.
> Всесвіт пакетів tidyverse - це набір пакетів, спеціально орієнтованих на data science.
```{r}
#!
# Display list of tidyverse packages.
tidyverse_packages() # Note, ggplot2 is also part of tidyverse
```
[1] "broom" "cli" "crayon" "dbplyr" "dplyr"
[6] "forcats" "ggplot2" "haven" "hms" "httr"
[11] "jsonlite" "lubridate" "magrittr" "modelr" "pillar"
[16] "purrr" "readr" "readxl" "reprex" "rlang"
[21] "rstudioapi" "rvest" "stringr" "tibble" "tidyr"
[26] "xml2" "tidyverse"
**Пакети Tidyverse роблять код простішим і швидшим.**
Оператор pipe **%>%** (з пакета *dplyr*) передає вихідні дані функції, застосовані до першого аргументу наступній функції. Такий спосіб об’єднання функцій дозволяє об’єднати декілька кроків одночасно, виконувати послідовні завдання.
```{r}
#Pass vector c(1,2,3,4,5) to the function mean()
a<-1:5 %>% mean()
a
```
Пакет *readr* спрощує читання або запис кількох форматів файлів за допомогою функцій, які починаються з read_* або write_*.
У порівнянні з R Base функції *readr* є швидшими.
```{r}
# mtcars.csv file we created above (see "Save/write and load/read data" section).
read_csv("mtcars.csv")
```
```{r}
# Analogically to base R, read_tsv reads .tsv files.