Пример - температура чая в чашке.
Значения не лимитированы фиксированными вариантами и могут принимать любые значения. Чем точнее прибор, тем точнее данные.
Пример - число чашек
Эти переменные по своей природе могут принимать только фиксированные значения.
Пример - субъективная оценка степени заварки чая:
I = так себе, II = средний, III = крепкий, IV = очень крепкий
Ранжированные данные похожи на непрерывные, но с потерей информации.
Допустим, мы не можем измерить объем чашек в миллилитрах, но можем оценить, в какую помещается больше всего, в какую - просто много, а в какую совсем мало. Мы можем расставить чашки по возрастанию объема и придать им номера - ранги - с которыми работать дальше.
Шаг между двумя соседними ранжированными величинами не обязательно одинаковый.
Пример - тип напитка в чашке.
Сами по себе они очень слабо поддаются обработке, потому что не являютя и с большим трудом переводятся в числа. Но если посчитать частоту встречаемости, то получатся cчетные данные.
Пример - сахар в чае: где
1 = есть, 0 = нет
Это информация о наличии/отсутствии признака.
Бинарные данные можно представить в виде логического вектора, то есть набора значений 0 и 1 или TRUE и FALSE.
Главная польза от бинарных данных в том, что в них можно перекодировать практически все остальные типы данных и применять специальные методы анализа.
В течение курса вы будете аккумулировать файлы для работы.
Надо организовать их особым образом чтобы дальнейшая работа шла без проблем.
В эту папку помещайте пожалуйста ВСЕ файлы со скриптами
В нее помещайте все файлы с данными для анализа
https://varmara.github.io/glmintro/
Вкладка "Презентации и данные", День 1.
Ваши задачи:
и сохранить его в папку R_course.
и сохранить его в папку data ВНУТРИ папки R_course.
Теперь ваша задча открыть файл скрипта
с помощью RStudio.
Русские буквы выглядят как непонятные кракозябры? Нужно поменять кодировку.
File -> Reopen with Encoding
Из предложенного списка выберете UTF-8
В том же окне со списком поставьте галочку "Save as default encoding for source files"
По умолчанию RStudio предлагает интерфейс из четырех окон:
Source. Это простой текстовый редактор, где открывается один или несколько файлов для работы со скриптами.
Console - командная строка, где "живет" R. В консоль отправляются на выполнение команды, здесь же R выводит результаты и пишет сообщения об ошибках.
Environment и History.
File, Plots, Help и другие.
Я предлагаю на время курса всем настроить расположение окон одинаково:
Source | Console |
---|---|
Environment | Plots |
Сделать это можно войдя в меню Tools -> Global Options -> Pane layout
Все что вы хотите чтобы R для вас сделал, нужно объяснять ему в виде команд. Если неясно, какая команда нужна для определенной операции, придется читать справочники.
Вам придется запомнить достаточно большое количество команд, готовьтесь. И как любой язык, R требует знания синтаксиса.
Сложности в работе обязательно будут, но не следует их бояться!
Ctrl + Enter
Главное сочетание клавиш при работе в RStudio.
Чтобы выполнить всю строчку надо поставить курсор в любое место этой строки и нажать Ctrl + Enter
Чтобы выполнить фрагмент строчки, надо выделить его и нажать Ctrl + Enter
Чтобы выполнить несколько команд одну за другой, надо выделить несколько строк и нажать Ctrl + Enter
Поставить курсор на название функции и нажать F1
Перед названием функции можно напечатать знак вопроса и выполнить эту строку
Можно воспользоваться функцией help()
?help # ИЛИ help("help")
R работает по принципу вопрос-ответ. Запущенная, программа ничего не делает и ожидает от вас команды. Вы набираете ее и отправляете в консоль. R что-то делает, выводит на экран результат, и переходит в режим ожидания следующей команды.
Знак >
говорит, что программа готова принимать команды.
Знак +
значит, что во введенной команде чего-то не хватает, и R ожидает продолжения. Один из самых частых случаев – потерялась закрывающая скобка.
Комментарии в тексте R-скрипта обозначаются символом '#'
# это комментарии, они не будут выполняться
2 + 2
## [1] 4
1024 / 2
## [1] 512
34 * 4
## [1] 136
2 ^ 4
## [1] 16
sqrt(27)
## [1] 5.2
Многоуровневые конструкции:
(10*(3-1))^-1
## [1] 0.05
Ответ программы находится на следующей строчке после команды. Здесь он начинается с [1]. Это значит, что программа рассчитала единственное значение.
Оператор присваивания это символ стрелочки <-
. Он работает справа налево:
куда_записывать <- что_записывать
Представим, что мы находимся в самом начале большого исследования чашек в нашей лаборатории, и пока только измерили температуру чая у себя в чашке.
Давайте создадим переменную tea_1
и присвоим ей значение 70
:
tea_1 <- 70
Чтобы увидеть содержимое переменной, достаточно позвать ее по имени:
tea_1
## [1] 70
Можно использовать только латинские буквы, цифры, нижнее подчеркивание и точку.
Имена не должны содержать пробелов, начинаться с точки или цифры.
R чувствителен к регистру, X и x — это разные имена
Нельзя давать объектам короткие, особенно однобуквенные, имена. Они могут быть уже заняты какой-то функцией, да и вы сами легко запутаетесь в таких переменных. Создавайте понятные и "говорящие" имена.
Варианты_названий | Качество |
---|---|
a, 1_х, wing color | плохо или недопустимо |
var1, var_1 | так себе, но допустимо |
shelllength | хорошо, но трудно читать |
shell_length, sp.count | хорошо: информативно, легко читать |
Ранее созданные переменные можно использовать в дальнейших рассчетах.
Допустим, за 10 минут чай в чашке остывает на 10 градусов. Какова будет его новая температура?
tea_2 <- tea_1 - 10
А на сколько градусов она уменьшится за 5 минут?
(tea_1 - tea_2) / 2
## [1] 5
Все переменные, что мы сейчас создали, представляют собой векторы одиночной длины.
C единственным значением бывает важно работать, но обычно данных у нас гораздо больше.
с()
от английского concatentate - собрать, склеить. Отдельные значения разделяются запятыми.Мы обошли своих соседей, и шестеро из них пили чай. Мы измерили температуру и у них тоже, и теперь готовы создать более серьезную переменную
tea_temp <- c(70, 64, 40, 91, 80, 83, 58)
rep
повторяет одно и то же значение сколько угодно разrep(-19, 4)
## [1] -19 -19 -19 -19
seq
нужна для создания векторов, где значения следуют одно за другим без пропусковseq(1, 10) # от одного до 10
## [1] 1 2 3 4 5 6 7 8 9 10
Почитайте help(seq) и самостоятельно создайте вектор чисел от -5 до 3 и с шагом 0.5
Функция принимает аргументы в таком порядке: seq(от, до, шаг)
seq(-5, 3, 0.5)
## [1] -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 ## [14] 1.5 2.0 2.5 3.0
Можно стоить многоуровневые конструкции
c(0, 2, rep(11, 5), -2, seq(51, 55, 2))
## [1] 0 2 11 11 11 11 11 -2 51 53 55
Векторы можно хранить в переменных для последующего использования
vector_1 <- seq(-11, 12, 1) vector_2 <- rep(0, 20)
При помощи оператора []
, можно обратится к некоторым элементам вектора. В квадратных скобках вам нужно указать один или несколько порядковых номеров элементов
tea_temp[1] # первый элемент в векторе температур
## [1] 70
vector_1[10] # 10-й элемент в векторе vector_1
## [1] -2
vector_1[22]
## [1] 10
Если нам нужно несколько элементов, то их нужно передать квадратным скобкам в виде вектора.
Какой результат даст команда:
vector_1[3:5]
А если задать вектор с номерами элементов при помощи функции c()
vector_1[c(1, 10)]
## [1] -11 -2
vector_1[c(2, 4, 6)]
## [1] -10 -8 -6
Что будет, если при обращении к вектору вы просто перечислили номера элементов через запятую?
vector_1[1, 3, 5]
Очень легко добавить в вектор значение, или объединить векторы. При этом не обязательно создавать новую переменную, можно и перезаписать старую.
Допустим, мы измерили температуру в еще одной чашке. Наша выборка растет! Чтобы перезаписать переменную tea_temp
нужно склеить старые значения с новыми и присвоить их переменной со старым именем:
tea_temp <- c(tea_temp, 88)
Узнаем количество значений:
length(vector_1)
## [1] 24
Сумма всех элементов вектора
sum(vector_1)
## [1] 12
Сумма разных векторов
sum(vector_1, vector_2)
## [1] 12
Математические операции
vector_1 + 2
## [1] -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 ## [23] 13 14
vector_1 * 2
## [1] -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 ## [17] 10 12 14 16 18 20 22 24
vector_1 ^2
## [1] 121 100 81 64 49 36 25 16 9 4 1 0 1 4 9 16 ## [17] 25 36 49 64 81 100 121 144
Кроме числовых, бывают и другие типы данных:
Каждый текстовый элемент (string) должен быть окружен кавычками
"это текст"
## [1] "это текст"
Текстовые значения можно объединять:
season<-c("winter","spring","winter","winter","spring", "spring","summer","summer","summer")
TRUE # истина
## [1] TRUE
FALSE # ложь
## [1] FALSE
Можно сокращать:
summer <- c(F, F, F, F, F, F, T, T, T) summer
## [1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE
Что мы получим, выполнив такую команду:
winter <- season == "winter"
Чтобы узнать, что за данные хранятся в переменной, используйте функцию str()
str(vector_1)
## num [1:24] -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 ...
str(season)
## chr [1:9] "winter" "spring" "winter" "winter" "spring" "spring" ...
str(winter)
## logi [1:9] TRUE FALSE TRUE TRUE FALSE FALSE ...
Не существует ни идельных наблюдений, ни идеальных экспериментов. Чем больше массив данных, тем больше вероятность встретить пропущенные данные. Они бывают нескольких типов.
Unknown, неизвестное значение. Измерение было не получено, не записано, или потеряно. Скажем, мы измеряли температуру чая в 20 чашках, отвернулись на минуту, и проходящий мимо коллега унес и выпил одну из них.
Not applicable, неприменимое значение. Мы обнаружили нечто, логически несовместимое с признаком, который надо фиксировать. Например, нам попалась чашка, полная земли, и в ней рос кактус!
И тот и другой варианты отличается по смыслу от нуля.
Возьмем пример с чашками чая. Ноль в качестве значения для нашей выпитой чашки будет означать, буквально, что в ней находился тающий снег. Это неверно отражает ситуацию, да еще и исковеркает нам последующий анализ.
Обойтись без пропущенных данных практически невозможно, поэтому важно выделять им места.
Пропущенное значение записывается как NA т.е. Not Available.
Вставим NA (допустим, из унесенной чашки) в вектор температур:
tea_temp <- c(tea_temp, NA)
Посмотреть, какие значения в векторе неопределены можно командой
is.na(tea_temp)
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Проверьте, есть ли пропущенные значения в векторе vector_2
Многие команды, при работе с пропущенными значениями, будут выводить результат NA:
sum(tea_temp)
## [1] NA
Чтобы узнать, почему и как это исправить - посмотрите в help("sum")
. Выяснится, что у функции sum()
есть аргумент na.rm
, который по умолчанию принимает значение FALSE
, то есть NA
не учитываются при подсчете суммы.
Если мы передадим функции sum
аргумент na.rm = TRUE
, то получится правильная сумма
sum(tea_temp, na.rm = TRUE)
## [1] 574
Работа в RStudio предполагает два сорта внешних источников: текстовые файлы со скриптами (например 1.1_intro_to_R_code.R который у вас сейчас открыт) и файлы с данными.
Рекомендуется запускать R из той же директории, где находятся файл со скриптом.
В R очень легко идти по дереву каталогов вниз, поэтому удобно иметь внутри рабочей директории со скриптом отдельную папку с таблицами данных.
На минутку сверните RStudio и удостоверьтесь, что у вас есть одна папка, в которой находятся файлы скриптов с расширением .R, и внутри - папка data содержащая таблицы данных.
Проверим, где мы сейчас находимся
getwd()
## [1] "/home/shade/Documents/TEACHING/STATISTICS/BIOCAD/GIT/glmintro"
Допустим, это не та папка, которая нужна.
Под Linux`ом можно прописать путь целиком:
setwd("/home/shade/Documents/WORK/2017_field_data/Baltic_Sea")
Но есть способ проще:
Выберите в меню Session -> Set working Directory... -> To Source File Location
Два самых популярных типа файлов для импорта данных в R это .cvs и .xls
Как организовать свои данные чтобы избежать мучительных переделываний и исправлений?
никаких пустых ячеек!
никаких русских букв
равное количество значений во всех строках
в идеале должно быть всего две колонки: значение признака и результат измерения
правила для названий переменных те же что в R. Главное - никаких пробелов
десятичная часть отделена точкой а не запятой
Формат csv черезвычайно хорош, поскольку в Excel или OpenOffice откроется как привычная глазу таблица. В то же время, это просто особым образом размеченный текстовый файл. Его можно и открыть в блокноте, и с легкостью загрузить в R.
Так как это по сути текст, клеточки таблицы передаются с помощью разделителей. Самые распространенные варианты: табуляция, точка с запятой, это хорошие варианты, а так же запятая и пробел - плохие.
Если будете создавать csv файлы, старайтесь использовать один из хороших вариантов.
После того как данные внесены и отформатированы, в R их загружает команда read.table("имя файла", sep=";", header=T)
Первый аргумент - имя файла, оно указывается в кавычках
sep
указывает разделитель. По умолчанию это пробел или табуляция, но можно записать и другое значение
Аргумент header
определяет судьбу названий столбцов. По умолчанию его значение FALSE. Чтобы названия были прочитаны и стали именами переменных, нужно указать TRUE.
Прочитаем файл с температурами "1.2_temperature.csv" находящийся в папке "data". Это вымышленные данные о температуре и типе напитков, обнаруженных нами в чашках наших коллег в течение года.
TEMP <- read.table("data/1.2_temperature.csv", header=T)
Посмотрим на несколько начальных строк:
head(TEMP)
## drink season temperature ## 1 tea fall 59 ## 2 coffee fall 60 ## 3 coffee fall 61 ## 4 coffee fall 60 ## 5 tea fall 60 ## 6 coffee winter 70
Как видим, все три переменные и их названия на месте.
Для дальнейшей работы с таблицей данных нам пригодятся три команды: две для индексации и одна - для извлечения фрагментов массива данных.
$
где_искать$что_искать
т.е. название_массива$название_переменной
TEMP$season
## [1] fall fall fall fall fall winter winter winter winter ## [10] winter spring spring spring spring spring summer summer summer ## [19] summer summer ## Levels: fall spring summer winter
x[i]
Чтобы найти все значения переменной, отвечающие какому-то условию, мы должны создать двухуровневую конструкцию. Например, нас интересует температура напитков весной.
Сначала сконструируем х: обратимся к переменной TEMP$temperature
Затем i: обратимся к переменной TEMP$season
и укажем, что нас интересуют значения TEMP$season == "spring"
TEMP$temperature[TEMP$season == "spring"]
## [1] 65 64 64 66 65
Аналогичную операцию можно проделать с помощью команды 'subset'. Отличие же заключается в том, что вместо вектора значений одной переменной, мы получаем маленький, но настоящий, массив данных.
Попробуйте сами получить фрагмент таблицы, включающий все данные относящиеся к кофе.
subset(TEMP, drink == "coffee")
## drink season temperature ## 2 coffee fall 60 ## 3 coffee fall 61 ## 4 coffee fall 60 ## 6 coffee winter 70 ## 7 coffee winter 70 ## 8 coffee winter 73 ## 9 coffee winter 68 ## 10 coffee winter 71 ## 14 coffee spring 66
Пакеты в R устанавливать очень просто - при условии что вы занете как они называются. Набираем команду:
install.packages("имя_пакета")
Установка происходит раз и навсегда. Но не каждый раз нам нужен именно этот пакет. Поэтому по умолчанию они не загружаются.
Чтобы использовать пакет в текущей сессии, загружаем его из библиотеки:
library(имя_пакета)
При установке название пакета должно быть в кавычках, при загрузке - без кавычек.