Язык R и анализ данных с примерами на Python

14 сентября 2018


Данные о качестве воздуха

head(airquality)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6
dim(airquality)
## [1] 153   6

В чем проблема?

mean (airquality$Ozone)
## [1] NA

Работа с отсутствующими данными

NA - пропущенное значение: is.na()

NaN - результат недопустимой арифметической операции: is.nan()

NULL - отсутствие субъекта: is.null()

Работа с пропущенными данными

Не учитывать пропущенные данные

mean(airquality$Ozone, na.rm = T)
## [1] 42.12931

Удалить строки с пропущенными данными

air <- na.omit (airquality)
dim (air)
## [1] 111   6
mean(air$Ozone)
## [1] 42.0991

Работа с пропущенными данными

is.na(airquality$Ozone)
##   [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
##  [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [23] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE
##  [34]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE
##  [45]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
##  [56]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE
##  [67] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
##  [78] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
##  [89] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [100] FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [111] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE
## [122] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [144] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE

Работа с пропущенными данными

sum(is.na(airquality$Ozone))
## [1] 37

Работа с пропущенными данными

which(is.na(airquality$Ozone))
##  [1]   5  10  25  26  27  32  33  34  35  36  37  39  42  43  45  46  52
## [18]  53  54  55  56  57  58  59  60  61  65  72  75  83  84 102 103 107
## [35] 115 119 150
anyNA(airquality$Ozone)
## [1] TRUE

NaN

0/0
## [1] NaN

Удаление столбцов

head(air,3)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
air$Ozone = NULL
head(air,3)
##   Solar.R Wind Temp Month Day
## 1     190  7.4   67     5   1
## 2     118  8.0   72     5   2
## 3     149 12.6   74     5   3

Факторы

Категориальные данные

f <- factor(c("yes", "yes", "no", "yes", "no"))
f
## [1] yes yes no  yes no 
## Levels: no yes
levels(f) 
## [1] "no"  "yes"

Факторы

levels(f) <- c(levels(f), "maybe") 
table(f) 
## f
##    no   yes maybe 
##     2     3     0

Факторы

Упорядочивание уровней факторов

f <- factor(c("yes", "yes", "no", "yes","no"), levels = c("yes", "no")) 
f
## [1] yes yes no  yes no 
## Levels: yes no

Факторы

boxplot(mtcars$mpg ~ mtcars$cyl)

plot of chunk unnamed-chunk-13

Матрицы

Внешне похожи на data frame

Вектор с атрибутом dim

Все элементы одного типа

Матрицы

m <- matrix(c(1:6), nrow=2, ncol=3)
m
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
m <- matrix(c(1:6), nrow=2, ncol=3,byrow=T)
m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6

Матрицы

as.matrix(1:3)
##      [,1]
## [1,]    1
## [2,]    2
## [3,]    3

Матрицы

m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
m[2,3]
## [1] 6

Матрицы

m[2,]
## [1] 4 5 6
m[,3]
## [1] 3 6

Матрицы

m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
m[2,3] = 1
m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    1

Матрицы

Создать пустую матрицу

m <- matrix(nrow=2, ncol=3)
m
##      [,1] [,2] [,3]
## [1,]   NA   NA   NA
## [2,]   NA   NA   NA
dim(m)
## [1] 2 3

Матрицы

v <- 1:6
dim(v)
## NULL
dim(v) <- c(2,3)
v
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
is.matrix(v)
## [1] TRUE

Матрицы

a <- c(1,2,3)
b <- c(7,8,9)
cbind(a,b)
##      a b
## [1,] 1 7
## [2,] 2 8
## [3,] 3 9
rbind(a,b)
##   [,1] [,2] [,3]
## a    1    2    3
## b    7    8    9

Матрицы

m
##      [,1] [,2] [,3]
## [1,]   NA   NA   NA
## [2,]   NA   NA   NA
rownames(m) <- c("r1","r2")
colnames(m) <- c("c1","c2","c3")
m
##    c1 c2 c3
## r1 NA NA NA
## r2 NA NA NA

Задание

Создать матрицу, состоящую из 100 чисел, принадлежащих нормальному распределению, и 20 строк

Замените любое значение в матрице на NA

Выведите количество строк, не содержащих NA

Списки

Можно хранить данные разных типов

L <- list("A", c(1,2), 30)
L
## [[1]]
## [1] "A"
## 
## [[2]]
## [1] 1 2
## 
## [[3]]
## [1] 30

Списки

L1 <- list (L, 40)
L1
## [[1]]
## [[1]][[1]]
## [1] "A"
## 
## [[1]][[2]]
## [1] 1 2
## 
## [[1]][[3]]
## [1] 30
## 
## 
## [[2]]
## [1] 40

Списки

L [[4]] = 'new_element'
L
## [[1]]
## [1] "A"
## 
## [[2]]
## [1] 1 2
## 
## [[3]]
## [1] 30
## 
## [[4]]
## [1] "new_element"

Списки

L [3]
## [[1]]
## [1] 30
L [[3]]
## [1] 30

Списки

L1 [[1]]
## [[1]]
## [1] "A"
## 
## [[2]]
## [1] 1 2
## 
## [[3]]
## [1] 30
L1 [[1]] [[2]]
## [1] 1 2

Списки

L <- list (10,20)
L$abc <- 123
L
## [[1]]
## [1] 10
## 
## [[2]]
## [1] 20
## 
## $abc
## [1] 123
names(L)
## [1] ""    ""    "abc"

Списки

L[[3]]
## [1] 123
L$abc
## [1] 123
L[["abc"]]
## [1] 123

Задание

Создать именованный список, элементами которого будут:

  1. числовой вектор
  2. список, состоящий из 3 элементов, одним из которых будет вектор длиной 3
  3. число
  4. строка

Вывести любое значение строкового вектора из предыдущего задания, пункт 2

Установка пакетов

install.packages ("dplyr")

library (dplyr)

library (dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Select

head(airquality,3)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
head (select(airquality, Wind, Temp), 3)
##   Wind Temp
## 1  7.4   67
## 2  8.0   72
## 3 12.6   74

Select

head(airquality,3)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
head (select(airquality, -Wind), 3)
##   Ozone Solar.R Temp Month Day
## 1    41     190   67     5   1
## 2    36     118   72     5   2
## 3    12     149   74     5   3

Select

head(airquality,3)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
head(select(airquality, Temp:Day))
##   Temp Month Day
## 1   67     5   1
## 2   72     5   2
## 3   74     5   3
## 4   62     5   4
## 5   56     5   5
## 6   66     5   6

Select

head(airquality,3)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
head(select(airquality, starts_with("T")))
##   Temp
## 1   67
## 2   72
## 3   74
## 4   62
## 5   56
## 6   66

Filter

air_filt<-filter(airquality, Temp > 70  & Month == 6)
head(air_filt)
##   Ozone Solar.R Wind Temp Month Day
## 1    NA     286  8.6   78     6   1
## 2    NA     287  9.7   74     6   2
## 3    NA     186  9.2   84     6   4
## 4    NA     220  8.6   85     6   5
## 5    NA     264 14.3   79     6   6
## 6    29     127  9.7   82     6   7

Filter

unique(airquality$Month)
## [1] 5 6 7 8 9
a <- filter(airquality, Month %in% c(7,8))
unique(a$Month)
## [1] 7 8

Задание

Как еще можно выбрать столбцы "Wind" и "Temp" из таблицы airquality?

Как еще можно отфильтровать таблицу airquality по значению столбца "Temp"?

Mutate

Добавление нового столбца

air_mut <- mutate(airquality, Temp_new = (Temp - 32) / 9)
air_mut <- mutate(air_mut, Temp_r = round(air_mut$Temp_new,2))
head(air_mut,4) 
##   Ozone Solar.R Wind Temp Month Day Temp_new Temp_r
## 1    41     190  7.4   67     5   1 3.888889   3.89
## 2    36     118  8.0   72     5   2 4.444444   4.44
## 3    12     149 12.6   74     5   3 4.666667   4.67
## 4    18     313 11.5   62     5   4 3.333333   3.33

Transmute

a <- transmute(airquality, Temp_new = (Temp - 32) / 9)
head(a,4)
##   Temp_new
## 1 3.888889
## 2 4.444444
## 3 4.666667
## 4 3.333333
dim(a)
## [1] 153   1

Summarise

summarise(airquality, mean(Temp, na.rm = TRUE))
##   mean(Temp, na.rm = TRUE)
## 1                 77.88235
mean(airquality$Temp, na.rm = TRUE)
## [1] 77.88235

Summarise

summarise(airquality, Mean = mean (Temp, na.rm = TRUE),
                      Min = min (Temp),
                      Max = max (Temp))
##       Mean Min Max
## 1 77.88235  56  97

Group by

summarise(group_by(airquality, Month), mean(Temp,na.rm = TRUE)) 
## # A tibble: 5 x 2
##   Month `mean(Temp, na.rm = TRUE)`
##   <int>                      <dbl>
## 1     5                       65.5
## 2     6                       79.1
## 3     7                       83.9
## 4     8                       84.0
## 5     9                       76.9

Sample

sample_n(airquality, size = 5) 
##     Ozone Solar.R Wind Temp Month Day
## 15     18      65 13.2   58     5  15
## 10     NA     194  8.6   69     5  10
## 26     NA     266 14.9   58     5  26
## 131    23     220 10.3   78     9   8
## 54     NA      91  4.6   76     6  23
sample_frac(airquality, size = 0.05) 
##     Ozone Solar.R Wind Temp Month Day
## 50     12     120 11.5   73     6  19
## 25     NA      66 16.6   57     5  25
## 75     NA     291 14.9   91     7  14
## 72     NA     139  8.6   82     7  11
## 80     79     187  5.1   87     7  19
## 46     NA     322 11.5   79     6  15
## 110    23     115  7.4   76     8  18
## 41     39     323 11.5   87     6  10

Count

count(airquality, Month) 
## # A tibble: 5 x 2
##   Month     n
##   <int> <int>
## 1     5    31
## 2     6    30
## 3     7    31
## 4     8    31
## 5     9    30

Arrange

air_sort<-arrange(airquality, desc(Month), Day) 
head(air_sort,4)
##   Ozone Solar.R Wind Temp Month Day
## 1    96     167  6.9   91     9   1
## 2    78     197  5.1   92     9   2
## 3    73     183  2.8   93     9   3
## 4    91     189  4.6   93     9   4

Объединение двух таблиц

a <- data.frame(id = c(1,2,3,4),
                name = c('A', 'B', 'C', 'D'),
                f1 = c('var1','var2','var2','var4'))

b <- data.frame(id = c(1,2,5,6),
                year = c(1990, 1995, 1998, 2000))

Объединение двух таблиц

a
##   id name   f1
## 1  1    A var1
## 2  2    B var2
## 3  3    C var2
## 4  4    D var4
b
##   id year
## 1  1 1990
## 2  2 1995
## 3  5 1998
## 4  6 2000

Объединение двух таблиц; inner_join

df <- inner_join(a, b, by = c('id'))
df
##   id name   f1 year
## 1  1    A var1 1990
## 2  2    B var2 1995

Объединение двух таблиц; left_join

df <- left_join(a, b, by = c('id'))
df
##   id name   f1 year
## 1  1    A var1 1990
## 2  2    B var2 1995
## 3  3    C var2   NA
## 4  4    D var4   NA

Объединение двух таблиц; right_join

df <- right_join(a, b, by = c('id'))
df
##   id name   f1 year
## 1  1    A var1 1990
## 2  2    B var2 1995
## 3  5 <NA> <NA> 1998
## 4  6 <NA> <NA> 2000

Конвеер

airquality %>% filter(Month != 5) %>%
group_by(Month) %>% summarise(mean(Temp, na.rm = TRUE))
## # A tibble: 4 x 2
##   Month `mean(Temp, na.rm = TRUE)`
##   <int>                      <dbl>
## 1     6                       79.1
## 2     7                       83.9
## 3     8                       84.0
## 4     9                       76.9

Без конвеера

filteredData <- filter(airquality, Month != 5)
groupedData <- group_by(filteredData, Month)
summarise(groupedData, mean(Temp, na.rm = TRUE))
## # A tibble: 4 x 2
##   Month `mean(Temp, na.rm = TRUE)`
##   <int>                      <dbl>
## 1     6                       79.1
## 2     7                       83.9
## 3     8                       84.0
## 4     9                       76.9

Основные понятия

Вектор, матрица, список, data frame в R

Конвеер