![]() |
||||
← |
Д. Шабанов, М. Кравченко. «Статистичний оракул»: аналіз даних в зоології та екології |
→ |
||
«Заповіді» організації даних, «жаб'ячий» файл-приклад, мова R тощо |
Використання мови R |
|||
«Статистичний оракул»-02 |
«Статистичний оракул»-04 |
Використання мови R
3.1. Початок роботи з R
ІЩоб почати працювати з R, його слід встановити. Інсталятор R завантажується тут. Як вже зазначено, для роботи з R ми будемо використовувати оболонку RStudio. Це також продукт, що дозволяє вільне використання (але є й платні версії). Інсталятор RStudio можна завантажити тут. Встановлювати RStudio слід обов'язково після R, а не до нього. Далі слід запускати саме RStudio і працювати в ньому.
Крім іншого, RStudio (і, через нього, R) можна запускати в онлайн-режимі (потребує регістрації та має певні обмеження).
Слід пояснити позначення, що будуть використовуватися в цьому посібнику. У цьому тексті ми будемо наводити імена функцій, використовувати назви об'єктів та досить часто наводити приклади команд. Щоб було зрозуміло, що певну послідовність символів можна застосовувати як команду («згодувати» R, припустимо, через RStudio, та отримати заплановану відповідь), ми будемо брати команди R у прямокутні рамки. Важливою частиною команд R є імена об'єктів, адреси тощо. У нашому викладенні ми будемо ставити на потрібні місця умовні позначення, набрані курсивом та великими літерами. Наприклад, команда is.logical(OBJECT$VARIABLE) перевіряє, чи є числовою змінна Variable в об'єкті Object. Цю команду можна скопіювати і вставити в консоль або редактор скриптів RStudio, але треба замінити назви об'єкту та змінної на ті, що потрібні.
Крім того, іноді ми будемо включати в текст результати, які R виводить у консолі. У такому разі весь такий фрагмент тексту ми будемо поміщувати у загальну рамку, як це зроблено нижче, в R-діалозі 3.1.1. Ми будемо нумеровати R-діалоги як таблиці, і будемо посилатися на них подібним чином.
R-діалог 3.1.1. Приклад виводу інформації у консолі RStudio: результат виконання найпростішої арифметичної операції
> # Приклад R-діалогу (після знаку # — коментарі) > 2 + 2 # Коментарі можна вставляти навіть у рядки після команд [1] 4 > |
Відразу слід пояснити, що можна побачити у R-діалогах. Це — RStudio console output, як це показано далі на рис. 3.4.1. Запрошення системи має вигляд знаку >. Те, що стоїть після нього — команди, які виконувалися (в цьому прикладі R шукав значення 2+2). Ця команда могла бути введеною прямо в консоль R, або ж у редактор кодів. У більшості випадків автори писали скрипти, запускали виконання їх фрагментів та переносили у структурні елементи підручника відповіді R з консолі RStudio.
У багатьох випадках (як показано в R-діалозі 3.1.1) елементи відповіді R нумеруються у квадратних лапках (до речі, в R, на відміну від багатьох мов програмування, перший елемент ряду має № 1, а не № 0). Відповідь на команду 2+2 складалася з одного елементу. Якщо б їх було настільки багато, що їх вивід зайняв би кілька рядків, на початку кожного стояв би номер першого елементу у рядку (наприклад, такий результат показано нижче, в табл. 3.6.1).
Читати R-діалоги слід таким чином. Після знаку > та символу # йдуть коментарі, що пояснюють те, що відбувається (вони необов'язкові). Те, що йде після знаку > та виділено напівжирним шрифтом — це команди R, які виконувалися (у тексті підручника їх маркує прямокутна рамка: 2 + 2). Після команд також можна додавати коментарі. Усе інше — відповіді R.
Інші особливості мови R стануть зрозумілі у подальшому обговоренні. Тут слід звернути увагу лише на такі обставини.
Багато виразів R мають вигляд a <- b. Його сенс такий: змінній (об'єкту, що має ім'я та значення) a привласнюється значення b. Звісно, можна було б писати a = b, але таке рішення є не рекомендованим, адже знак = використовується в інших ситуаціях. Щоб швидко вставити у код сполучення <-, можна одночасно натиснути Alt та -.
Ще одна особливість R полягає в тому, що, незалежно від регіональних стандартів, десятковим розділювачем в ньому є точка. 1.5 — це один та п'ять десятих, а 1,5 — текстовий вираз, що не є числом.
3.2. RStudio — оболонка для роботи з R
RStudio — вільне інтегроване середовище розробки, призначене для R. Вікно RStudio складається з декількох панелей, серед яких особливу увагу слід звернути на панель Source, редактор скриптів (script), тобто збережених послідовностей команд, та панель Console, консоль, (рис. 3.2.1).
Рис. 3.2.1. Вікно RStudio під час роботи. Основні елементи: редактор скриптів (згори ліворуч), консоль (унизу ліворуч), оточення та історія (згори праворуч), графіки (унизу праворуч)
На рис. 3.2.1 можна побачити типову картину роботи з RStudio. В окні редактора скриптів відкрито скрипт Sperm.R (*.R — типове розширення скриптів). Цей скрипт було виконано (його виділили сполученням клавіш Ctrl+A, і після цього натиснули кнопку Run). В консолі можна побачити результати виконання скрипту (у редакторі видно покаток низки команд, а у консолі — результат виконання останніх команд). У виконаному скрипті спочатку задавалося робоча директорія, підгружався та активувався необхідний пакет, а після цього — створювалася таблиця, яка також має назву Sperm. Ці етапи пояснювалися у скрипті. Для цього використовують рядки, що починаються з символу #; усе, що йде після цього символу, програма ігнорує, але демонструє зеленим кольором для користувача.
В об'єкт (фрейм даних, таблицю) Sperm завантажується інформація з файлу, який було створено у електронних таблицях (в Calc). Об'єкт Sperm можна побачити у вікні Environment. Після того, як цей об'єкт було створено, згідно з заданою у скрипті послідовністю дій було побудовано низку графіків. Для цього було використано функцію qplot, що входить у склад пакету ggplot2. У скрипті послідовно створюється низка графічних об'єктів, які будує функція qplot. Аргументи цієї функції задають змінну, об'єкт, тип графіку, підписи осей координат, підпис графіку в цілому. Створені графіки один за одним демонструються у вікні Plots, а потім окремою командою зберігаються у робочій директорії. Їх характеристики можна подивитися у вікні Environment; крім того, можна перейти на вкладку Files, щоб передивитися будь-який з цих файлів.
Під час створення скрипту буває корисним пробувати різні варіанти команд. Їх можна вводити відразу у консоль. Тільки-но ви закінчили писати рядок у консолі та написнули Enter — цей рядок буде виконано. Панель Console дозволяє виконувати окремі команди, в ній відбивається результат виконання команд, поданих як з цього вікна, так і з редактора кодів. Але іноді має сенс виконувати не окремі команди, а їх більш-менш довгі послідовності або скрипти цілком. Саме тут стає у нагоді
На рис. 3.2.1 видно результати виконання скрипту цілком. Це — не єдиний можливий варіант. Часто корисно виконувати скрипт покроково. Для виконання поточного рядку коду можна скористатися поєднанням клавіш Ctrl+Enter або кнопкою Run Line(s), що розташована у верхній частині вікна редактора. Код буде виконаний, і курсор переміститься на наступний рядок. Для виконання відразу декількох рядків (або частини рядка) треба виділити необхідний фрагмент і натиснути клавіші Ctrl+Enter або Run Line(s). Щоб виконати всі рядки скрипту, слід або виділити його цілком, або натиснути Ctrl+Shift+Enter.
Ctrl+1 — переміщує курсор у вікно редактора скриптів; Ctrl+2 — переміщує курсор в консоль; Ctrl+L — очищає вікно консолі від тексту; Esc — перериває обчислення.
Панель History (історія) дозволяє переглянути історію команд, виділити деякі з них і відправити в консоль (Send to Console) або в редактор скриптів (Send to Source).
3.3. Типи об'єктів. Пакети
Як вже сказано, в R є data objects та function objects. Типові data objects в R такі:
— вектор (vector);
— матриця (matrix);
— масив (array);
— часовий ряд (ts);
— фрейм даних, датафрейм, таблиця (data frame);
— фактор (factor);
— список (list).
Найпростішим об'єктом в R є вектор (іменований одновимірний об'єкт, що містить дані одного певного типу); навіть число розглядається у цій мові як вектор одиничної довжини. Атрибутами вектора є як значення, які він містить, так і тип даних в ньому. Існують такі прості типи векторів та інших об'єктів, що можуть бути побудованими з векторів:
— логiчний (logical) — елементи «iстинно» (TRUE, T) та «хибно» (FALSE, F);
— числовий (numeric) — дiйсні числа;
— цiлий (integer) — цiлі числа;
— комплексний (complex) — комплексні числа;
— символьний (character) — символьнi рядки.
Вектори можуть мати усі ці типи даних — але лише один у одному векторі. Вектор може бути логічним, може бути цілочисловим, але неможливо поєднати логічні та цілочислові дані в одному векторі.
Кілька послідовних векторів однакової довжини утворюють матрицю — двомірний об'єкт або масив — багатомірний об'єкт. Дані в векторі, матриці або масиві повинні мати однаковий тип. На відміну від них фрейми даних можуть складатися з векторів, що мають різні типи даних. Наприклад, файл з даними PelophylaxExamples, який ми розглядали у попередній темі, за своєю будовою є прикладом фрейму. За своєю будовою цей файл описує двовимірну структуру, де різні стовпці (вектори) містять або числові, або символьні дані.
Часові ряди подібні до векторів, але відбивають певну часову послідовність, містять частоту спостережень та дату. Списки побудовані як вектори, але складаються з об'єктів, що можуть містити дані різних типів. Фактори — це аналоги векторів, значення яких можуть братися лише з певного переліку. Значення, які може набувати фактор, називають його рівнями (levels). Наприклад, якщо нас цікавить температура тіла певної кількості хворих, ми можемо задати її у числовій формі (36.7, 35.1, 38.7, 36.6, 42.1, 36.5, 37.8,...), а можемо використати фактор (нормальна, знижена, підвищена, нормальна, крітично підвищена, нормальна, підвищена, ...); з цього прикладу зрозуміло, які рівні може приймати обговорюваний фактор.
Об'єкти можуть бути організовані в пакети, package. Пакети можуть входити до складу бібліотек, library. Використання пакетів є причиною того, що хоча мова R є досить простою, її мінімальний набор можливостей може майже необмежено розширятися. Величезна кількість програмістів та вчених розробляють нові функції, що можуть бути реалізовані в R. До речі, пакети можуть бути написані як на мові R, так і на інших мовах. Ці пакети можна отримувати зі сховища і додавати до складу мінімальної реалізації R, яка отримується під час інсталяції. Кількість доступних пакетів для R на час написання цього тексту ставить близько 16 тисяч; вони перекривають майже усі статистичні процедури, що розроблені людством. Хоча для початку роботи з R треба подолати досить високий поріг входження, в подальшому ці зусилля сторицею виправдовуються завдяки можливості використовувати різноманітні розширення для R.
Інформацію про пакет можна отримати так: library(help=PACKAGE). В інсталятор R включені базові (base) і рекомендовані (recommended) пакети. Дізнатися, які пакунки встановлено на комп'ютері, можна командою library(). Щоб додати пакет, його потрібно спочатку завантажити install.packages("PACKAGE"), а потім включити: library(PACKAGE). Зверніть увагу, що у першому випадку назву пакету узято у лапки, а у другому — ні; неврахування такого роду деталей є поширеною причиною помилок у роботі R. Як багато інших функцій, функція install.packages може використовуватися з необов’язковими атрибутами. Наприклад, якщо вказати install.packages("PACKAGE", dependencies = TRUE), у разі, якщо для нормальної роботи пакету PACKAGE необхідні якісь інші пакети, вони встановляться разом. Якщо спробувати звернутися до функції пакета, який ще не включено у системі, R видасть повідомлення про помилку.
Як ми сказали, у цьому курсі ми будемо користуватися комплексом пакетів tidyverse. Для цього треба один раз на певному ком'ютері виконати команду install.packages("tidyverse"), а потім починати ті скрипти, де будуть використовуватися функції з цього комплексу, рядком library(tidyverse). Ця команда підвантажить наступні пакети: ggplot2, що призначено для побудови графіків та візуалізації результатів; tibble, для роботи з тібблами, оновленою версією фреймів даних; tidyr, для підтримки формату tidy data; readr, для читання файлів в R; purrr, для функціонального програмування; dplyr, для перебудови даних; stringr, для роботи з рядковими змінними; forcats, для роботи зі змінними-факторами.
Характерною ознакою функцій є круглі дужки, у які вміщуються аргументи, що задають об'єкти, з якими працюють функції, та особливості їх роботи. Звісно, є функції, що використовуються буз дужок, як-от арифметичні операції. Але це виключення. Деякі функції навіть не мають аргументів, але усе рівно застосовуються з дужками. Наприклад, команда: ls() виведе перелік об'єктів, які зараз активні у оточенні, environment, програми. У дужки у даному випадку не треба нічого ставити, вони просто демонструють, що ми маємо справу з функцією. Якщо ми введемо команду ls , ми отримаємо у консолі RStudio код функції ls(). Крім того, щоб отримати допомогу по використанню функції, можна ввести її ім'я зі знаком питання ?ls(); справка з'явиться у правому нижньому вікні RSudio. До того ж самого результату приведе команда help(ls). Щоб отримати список аргументів якоїсь функції (наприклад, lm(), яка забезпечує підгонку лінійних моделей), можна використовувати функцію args(): args(lm).
У ході роботи з R вам доведеться створювати об'єкти та надавати їм імена. Імена об'єктів мають починатися з букви, не можуть мати пробіли, але можуть мати крапки. Деякі імена, які зайняті під назви функцій R, використовувати, по зрозумілим причинам, неможливо.
Скрипт R складається з рядків, кожен з яких є певною командою. У разі, якщо у один рядок треба записати дві послідовні команди, їх розділюють точкою з комою(;). Записані у різні рядки команди ніяк особливо розділяти не треба. Якщо команда не вмістилася у один рядок, її можна продовжувати у наступному — R зрозуміє, що це не нова команда, а продовження старої, адже інтерпретатор цієї мови аналізує синтаксис команди. Як ви можете зрозуміти, незакриті дужки (чи інші порушення синтаксису) призведуть до помилок.
Під час написання скрипту його можна супроводжувати поясненнями. Як вже вказано, пояснення розміщуються праворуч від символу #. Цей символ можна помістити після певної команди скрипту або на початку рядка. Програма буде ігнорувати усе, що написано після символу # до самого кінця рядка.
3.4. Початок роботи
Ви зайшли в RStudio. Ще нема ані завантаженого скрипту, ані файлу з даними. Якщо є бажання або потреба, на цьому етапі RStudio можна використовувати як калькулятор (рис. 3.4.1).
Рис. 3.4.1. RStudio вирахував вираз, який було уведено до консолі. В вікні History лишився запис про цей крок. Саме цей приклад консольного виводу показано в таблиці 3.1.1
Підтвердженням того, що система готова до роботи, є символ >. Команди, що вводяться у консоль, підсвічуються синім. Після того, як команду уведено, система видає результати. Результати, які виводить R, нумеруються, починаючи з [1].
Скоріше за все, RStudio має працювати з якимось файлами. Їх можна створити прямо в програмі, а можна загрузити; більш поширеним є другий варіант. Спочатку слід зазначити робочу директорію для R, як це було зроблено на прикладі, показаному на рис. 3.2.1. Зручно, коли кожен окремий аналіз, окремий файл даних, з яким працюють у R, знаходиться у своій директорії. Створимо директорію для аналізу, з яким будемо працювати, Робочий файл слід або помістити в робочу директорію RStudio, або розмістити там, де треба, змінивши в RStudio робочу директорію. Щоб вказати робочу директорію засобами RStudio, слід пройти наступним шляхом: Session / Set Working Directory / Choose Directory. Крім того, можна просто увести команду setwd("PATH"). Шлях до директорії треба вказувати повністю, з фізичного або логічного диску у Windows або материнської директорії у Linux. Наприклад, в Ubuntu (один из вариантов операційної системи Linux), де працює один з авторів цього тексту, команда, що вказує робочу директорію, є такою: setwd("/home/dsh/R").
Розглянемо для початку приклад створення файлу даних прямо під час R-сесії. Уведемо дані про довжину тіла (L) та ширину голови (Ltc) представників Pelophylax lessonae з файлу PelophylaxExample. Для цього ми створимо два вектори, один — для змінної L, другий — для Ltc. Перша жаба буде першою в обох цих векторах, друга — другою тощо. Щоб створити вектори, використаємо операцію привласнення: задамо ім'я, використаємо символ <- і функцію c(), яка перетворює свої аргументи на вектор або список (combine).
Якщо редактор скриптів закрито, відкроємо його сполученням Ctrl+1. Введемо в нього наступний текст:
L <- c(603, 562, 592, 595, 602)
Ltc <- c(194, 187, 195, 199, 218)
plot(L, Ltc)
В двох перших командах ми використали характерний для R символ присвоєння: <-. Його значення просте: певному імені слід поставити у відповідність певни' об'єкт. Саме так у R створюють нові об'єкти. Тут використано також функцію c(), що поєднує об'єкти у вектор. Цими командами ми створюємо два вектори, кожен з яких містить по п'ять елементів. Перший вектор містить дані про довжину тіла жаб, другий — дані про ширину їх голови. У третьому рядку ми даємо команду побудувати за цими даними найпростіший графік за допомогою функції plot(), для цього ми вказуємо цій функції, які дані слід відкладати на вісях нашого графіку.
Виділимо усі три рядки у редакторі скриптів та натиснемо кнопку Run (або послідовно будемо ставити курсор після кожного з рядків команд та натискати Ctrl+Enter). Ось що ми отримаємо (рис. 3.4.2):
Рис. 3.4.2. Безпосередньо у RStudio було створено найпростіші об'єкти з даними та побудовано графік
У редакторі скриптів — текст команд, які були виконані. У консолі — виконані команди. У вікні Environment — два створені вектори. У вікні Plots — побудований відповідно до поданої команди графік. Звісно, можливості R не обмежені графіками.
Додамо у редактор скриптів (звісно, якщо є бажання, можна ввести їх прямо у консоль) наступні команди:
cor(L, Ltc)
cor.test(L, Ltc)
cor.test(L, Ltc, method = "spearman")
Результат буде таким (R-діалог 3.4.1).
R-діалог 3.4.1. RStudio console output. Приклад розрахунку коефіцієнтів кореляції
> cor(L, Ltc) # Обчислення коеффіцієнту кореляції Пірсона [1] 0.6296008 > cor.test(L, Ltc) # Більш детальна інформація щодо коеффіцієнту кореляції Пірсона Pearson's product-moment correlation data: L and Ltc t = 1.4036, df = 3, p-value = 0.255 alternative hypothesis: true correlation is not equal to 0 95 percent confidence interval: -0.5683954 0.9719646 sample estimates: cor 0.6296008 > cor.test(L, Ltc, method = "spearman") # Обчислення коеффіцієнту кореляції Спірмана Spearman's rank correlation rho data: L and Ltc S = 12, p-value = 0.5167 alternative hypothesis: true rho is not equal to 0 sample estimates: rho 0.4 > |
Після знаку > R виводить відповіді на подані команди. Функція cor(FIRST, SECOND) є самою простою. У відповідь R просто розраховує коефіцієнт кореляції за Пірсоном; можна впевнитися, що він складає приблизно 0,63. Якщо нас цікавить значущість отриманого коефіцієнту, нам потрібна функція cor.test(FIRST, SECOND). У відповідь R виведе більш детальний звіт. Можна побачити, що p=0,24, тобто коефіцієнт кореляції не є значущим: такі відносини між значеннями двох векторів могли з'явитися просто внаслідок випадковості і не обов'язково свідчать про наявність зв'язку між ними. Цікаво, що у 95% довірчий інтервал значень коефіціенту кореляції Пірсона входить навіть негативна кореляція між розглянутими векторами. Причину неважко зрозуміти: 5 особин є зовсім невеликою вибірку і, дійсно, спостережуване співвідношення між зареєстрованими значеннями з досить великою ймовірністю може бути результатом випадковості.
Як ми будемо обговорювати пізніше, коефіцієнт кореляції Пірсона є параметричним методом; він засновується на припущенні, що вибірки отримані з генеральної сукупності, що має нормальний розподіл. Якщо ми не знаємо, яким є розподіл досліджуваних ознак, слід використовувати коефіцієнт кореляції Спірмана. Щоб отримати розрахунок цієї величини, у команду слід додати відповідний атрибут cor.test(FIRST, SECOND, method = "spearman"). Можна побачити, що потужність цього методу є меншою за попередній (це типово для переходу від параметричних до непараметричних методів).
Якщо ми почали обговорювати команди R, слід згадати про одну його дуже важливу особливість. Він розуміє лише правильно подані команди! З іншого боку, чи могло бути якось інакше?
Пояснемо це за допомогою R-діалогу 3.4.2.
R-діалог 3.4.2. Чому щось пішло не так?
> a <- c(1,2,3) # створюємо вектор з трьох чисел > a # викликаємо створений вектор, щоб R вивів його у косолі [1] 1 2 3 > b <- с(4,5,6) # як здається, повторюємо аналогічну операцію... Error in с(4, 5, 6) : could not find function "с" > b Error: object 'b' not found > |
Ми створили вектор a та вивели його у консоль. Потім, здається, ми зробили те ж саме з вектором b, але отримали повідомлення про помилки. Чому? Щоб знайти відповідь, ви можете скопіювати наведені команди з R-діалогу, вставити їх у RStudio та встановити, що треба виправити, щоб вони працювали як треба.
Зрозуміли?
3.5. Читання файлів *.csv
Робота в R найчастіше йде з фреймами даних, DataFrame. Для початківців в R типовою може бути ситуація, коли вже наявний файл з даними слід перенести в це середовище. Серед інших форматів R приймає файли з розширенням *.csv, Comma-Separated Values. Це поширений формат, який можна використовувати у якості шлюзу між різними програмами. Фактично, це текстовий файл, де дані таблиці представлені у вигляді рядків. Окремі комірки таблиці при цьому відділяються певним знаком пунктуації (в стандартному випадку це — коми). Прикладом такого файлу може бути PelophylaxExample.csv, посилання на який вже наводилося раніше.
Якщо б у файлі PelophylaxExamples.csv комірки були б розділені комами, а десятковим знаком була б точка, щоб відкрити його у RStudio або напряму у R, було б достатньо увести команду PE <- read.csv('PelophylaxExamples.csv'). Ця команда читає файл PelophylaxExamples.csv, який має бути розташованим у робочій директорії R, та зберігає результат читання як фрейм, що має ім'я PE. На жаль, у даному випадку ця команда без необхідних уточнень не спрацює. Річ у тім, що під час створення цього файлу були використані інші роздільники (рис. 3.5.1), адже файли *.csv можуть бути різними.
Рис. 3.5.1. Створення файлу PelophylaxExamples.csv в LibreOffice Calc. Десятковий роздільник — кома, між полями — крапка з комою
Зберегти таблицю в форматі *.csv можна в Exсel, Calc та багатьох інших програмах через пункт меню «Зберегти як...». Втім, з тими настройками, з якими найчастіше доводиться мати справу користувачам в Україні, Exсel використовує коми як десяткові роздільники. Для відокремлення комірок таблиці в такому випадку Exсel буде використовувати крапку з комою. Щоб прочитати файл *.csv, який було зроблено так, як на рис. 3.5.1, слід використати таку команду PE <- read.csv('PelophylaxExamples.csv', sep = ";", dec = ",").
Зазвичай, перший рядок таких таблиць, як показано на рис. 3.5.1, містить назви стовпців. Щоб їх напевно прочитати, можна додати аргумент, що підкреслить наявність заголовків: PE <- read.csv('PelophylaxExamples.csv', sep = ";", dec = ",", header = TRUE). Втім, у даному випадку це необов'язково: R зрозуміє, що має справу з заголовками і без цього. А ось коли заголовків нема, може бути потрібним використати аргумент ..., header =FALSE).
До речі, певні труднощі можуть виникати при читанні файлів, де є кирилиця (найпростіше рішення — не використовувати її в статистичних файлах загалом!). Коли кирилиця читається неправильно (замість з дитинства знайомих літер, що заспокоюють та викликають довіру, — «козявушки», вони ж «кракозябри», що травмують психіку), слід встановити, з яким кодуванням було збережено файл *.csv та вказати необхідне кодування окремим атрибутом, наприклад OBJECT <- read.csv('FILENAME.csv', sep = "SIMBOL", dec = "SIMBOL", encoding = "UTF-8") або OBJECT <- read.csv('FILENAME.csv', encoding = "Windows-1251").
Зверніть увагу! Як це зроблено у попередній команді, ім'я файлу слід вводити з одинарними прямими лапками, а символи, які треба використовувати як розділювачі, — брати у подвійні прямі лапки. Загалом, важливим джерелом помилок, які можуть перешкоджати роботі в R, є плутанина з подібними один на одного символами. Наприклад, причина колізії, що показана в R-діалозі 3.4.2, в тому, що в другому випадку замість літери c з латиниці використано літеру с з кірилиці (воні знаходяться на клавіатурі в одному місці та не відрізняються одна від одної, і тому їх дуже легко переплутати). Дещо подібний комплекс проблем пов'язаний і з лапками. Наприклад, якщо ви напишете так: sep = “;”, R його просто нічого не зрозуміє. Подвійні (як і одинарні) лапки повинні бути прямими, тобто такими, які в найбільш поширеній розкладці ставляться при натисканні клавіші, що відповідає за українську літеру «Є» або російську — «Э» (до речі, ось приклад третього типу лапок). Щоб R виконав команду, треба писати виключно sep = ";"). На щастя, ви можете побачити, чи «розуміє» вас RStudio. Якщо RStudio приймає синтаксис введеного тексту, він підсвічує назви файлів, роздільники і інші елементи набраного користувачем тексту (рис. 3.5.2).
Рис. 3.5.2. «Підсвічування» елементів тексту в RStudio: у другому рядку ім'я файлу і знак десяткового розділювача (dec) підсвічені зеленим, а знак розділювача комірок (sep) — ні (там використано неправільні лапки)
Загалом, в RStudio є достатньо зручні засоби допомоги під час створення команд. Припустимо, ми плануємо роздивитися структуру створеного фрейму з використанням команди str(NAME). Під час набору назви функції RStudio у віконці, що спливає (хінті), запропонує варіанти, що починаються подібним чином, та виведе нагадування про властивості цих функцій (рис. 3.5.3). RStudio запропонує можливі варіанти продовження початого тексту під час зупинки у наборі або при натисканні клавіши Tab.
Рис. 3.5.3. Спливаючі віконця в RStudio можуть бути дуже корисними; викликати підказку можна клавішею Tab
До речі, наслідком виконання обговорюваної команди буде наступний вивід (R-діалог 3.5.1).
R-діалог 3.5.1. Структура фрейму PE
> str(PE) # Виклик структури фрейму PE 'data.frame': 57 obs. of 15 variables: $ X : Factor w/ 57 levels "LL_f_562","LL_f_592",..: 4 1 2 5 3 9 16 10 13 7 ... $ Place : Factor w/ 25 levels "Balakliya","Chernetchina",..: 12 2 2 2 2 11 5 5 13 13 ... $ East : num 35.2 35.1 35.1 35.1 35.1 ... $ North : num 50.1 50 50 50 50 ... $ Basin : Factor w/ 2 levels "Dnipro","Don": 1 1 1 1 1 2 2 2 2 2 ... $ Sex : Factor w/ 2 levels "female","male": 1 1 1 2 1 1 2 1 2 1 ... $ DNA : num 14 13.9 14 13.9 14 ... $ Genotyp: Factor w/ 5 levels "LL","LLR","LR",..: 1 1 1 1 1 2 2 2 2 2 ... $ L : int 603 562 592 595 603 625 589 658 528 557 ... $ Ltc : int 194 187 195 199 218 221 216 241 196 200 ... $ Fm : int 264 266 281 285 287 303 290 306 257 251 ... $ T : int 255 249 261 286 281 292 277 304 246 257 ... $ Dp : int 76 62 79 75 80 83 77 96 66 67 ... $ Ci : int 42 41 37 38 45 37 37 34 31 33 ... $ Cs : int 119 152 132 114 158 145 152 170 127 143 ... > |
Ви прочитали файл *.csv і створили об'єкт R (у нашому прикладі він отримав ім'я PE). Що далі? Як припинити роботу з цим об'єктом, а потім повернутися до його аналізу знову? Тут можливі три рішення. Перше — залишити, як є. Виходячи, зберігти робочій простір (Workspace) в RStudio (на рис. 4.5.4 показано, як RStudio пропонує це зробити). Входячи наступного разу, відкрити робочий простір та продовжати роботу з об'єктами, що там містяться.
Рис. 3.5.4. В RStudio був відкритий та виконаний скрипт. При закриванні програми вона пропонує зберігти робочий простір (з розширенням *.RData) та скрипт (з розширенням *.R)
Це рішення (зберігати об'єкти у робочому просторі) має суттєві недоліки. Працюєте ви, працюєте з певним об'єктом, пересилаєте комусь скрипт, і несподіванно узнаєте, що ваш скрипт працює лише з якимось об'єктом, що висів у робочому просторі, ви його видалили, і як його створювати встигли забути. Незручно.
Інше рішення також просте. Ви можете будь-який сеанс роботи з вашим файлом даних починати з читання файлу *.csv. Тут також є проблеми. Під час аналізу файлу даних у нього вносяться корективи: створюються нові змінні, додаються якісь виправлення та добавки... Якщо діяти таким чином, скрипт, що вирішує якусь задачу, що вирішується після багатьох кроків аналізу, має містити в собі усю історію змін файлу даних. Раз за разом, виконуючи скрипт, ми будемо читати дані, виправляти в них помілки, створювати нові стовпці тощо. Якщо ми вирішемо переслати такі дані комусь, ми будемо примушені додавати повний комплект внутрішньої кухні: надсилати файл *.csv та зафиксовану у скрипті усю його сумну історію. Є ситуації, коли такий підхід загалом не працює. Зараз у багатьох наукових журналах у додаткові матеріали до статті можна додати файл з даними, але зрозуміло, що цей файл має бути максимально простим для розуміння.
У більшості випадків оптимальне рішення - зберегти дані у фоматі R з використанням команди save(PE, file = "PelophylaxExamples.RData"). Ця команда збереже файл у робочу директорію; в ній вказано, що саме треба зберігти, вказано, що зберігати треба у файлі та вказано ім'я цього файлу з розширенням *.RData. В цю команду можна додати адресу; наприклад, на комп'ютері автора (що використовує операційну систему Linux; Windows-адреси мають іншій формат) ця команда виглядає так: save(PE, file = "/home/dsh/R/Course/PelophylaxExamples.RData"). Отриманий файл можна буде у будь-який момент прочитати командою load("/home/dsh/R/Course/PelophylaxExamples.RData") (якщо файл розташовано у робочій діректорії, адресу можна на вказувати), пересилати іншим людям електронною поштою і навіть включати у додаткові матеріали до публікації.
3.6. Перегляд даних на прикладі фрейму PelophylaxExample
Наприкінці попереднього пункту наведено відповідь R на команду str(PE). Перелічено кількість рядків (observations) і стовпців (variables). Побудова фрейму даних відповідає найпоширенішому статистичному стандарту. Рядкам відповідають окремі спостереження, окремі порівнювані об'єкти; стовпцям — змінні, ознаки цих об'єктів. Спочатку вказано тип об'єкту, а також загальну кількість спостережень та змінних, а після цього наведено перелік змінних та значення перших 10 спостережень. Назви змінних йдуть після символу $. так, PE$Place — це змінна з назвами місць збору досліджуваних особин. Перший стовбчик з кодами жаб не мав назви; R позначив його як PE$X.
Можна побачити, що R самостійно визначив, до яких типів (відповідно до наведеної вище класифікації) належать змінні у файлі. Ті стовпці, де стояли текстові значення, трактуються як фактори. R зазначає кількість рівнів (значень) цих факторів. Поки що вони розташовані за алфавітом. Після того, як R навів приклади двох рівнів, він перелічує рівні, що є характерними для перших 10 об'єктів.
Змінні, де знаходилися числа з десятковими знаками (географічні координати та кількість ДНК), трактуються як числові (numeric) вектори. Там, де булі лише цілі значення, вектори є цілочисловими (integer).
Що б було, якщо б ми позначали стать жаб числами (1 та 2)? R вирішив би, що це цілочислений вектор. Якщо б ми захотіли порівнювати самиць та самців, нам би довелося спеціальною командою повідомити R, що це — фактор. Саме такою була ситуація у прикладі, що був показаний на рис. 3.2.1. У стовпці Sperm$Male там знаходилися номери різних самців, а у стовпці Sperm$Sample — номери проб. Щоб порівнювати різних особин або ж різні проби, треба було зробити ці змінні факторами. Саме тому там подавалися команди Sperm$Male <- factor(Sperm$Male) та Sperm$Sample <- factor(Sperm$Sample).
А що буде, якщо ввести ці команди у тому скрипті R, де було створено фрейм PE? R повідомить про помилку: в його оточенні в цьому сеансі відсутній фрейм Sperm. А як перевірити, чи є певна змінна фактором? За допомогою команди is.factor(DATAFRAME$VARIABLE). За допомогою іншої команди можна перевести стовпчик у потрібний тип: as.integer(DATAFRAME$VARIABLE). Відповідь системи буде приблизно такою (R-діалог. 3.6.1). Зверніть увагу, як пронумеровані елементи вектора. У перший рядок вмістилося 36 значень, перше значення у другому рядку має № 37.
R-діалог 3.6.1. RStudio перетворив фактор у цілі числа та вивів його у консолі
> is.factor(PE$Sex) # Перевірка, чи є змінна Sex фактором [1] TRUE > as.integer(PE$Sex) # Перетворення змінної на фактор [1] 1 1 1 2 1 1 2 1 2 1 2 2 1 1 1 1 2 1 2 1 1 2 2 1 2 1 2 2 1 1 2 2 2 1 2 1 [37] 1 1 2 2 1 1 2 2 2 1 1 1 1 2 1 1 1 2 2 2 2 > |
У останньому прикладі R просто навів усі значення переведеного у цілочисловий режим вектора. У перший рядок вмістилося 36 значень, і R показав, що починає наступний рядок з тридцять сьомого елемента.
До речі, ви зрозуміли, що результат команд Sperm$Male <- factor(Sperm$Male) та as.factor(Sperm$Male) буде відрізнятися лише тим, якій звіт виведе R у консолі? Вибір між такими альтернативами і характеризує стиль програмування, що є характерним для кожного користувача.
Крім функції str() для того, щоб познайомитися з фреймом дуже корисною може бути функція summary().
R-діалог 3.6.2. Результат виконання функції summary()
> summary(PE) # Функція summary() надає багато корисної інформації X Place East North LL_f_562 : 1 Gaydary : 7 Min. :35.13 Min. :49.09 LL_f_592 : 1 Verbunivs`kaDacha: 6 1st Qu.:36.31 1st Qu.:49.42 LL_f_602 : 1 DobritzkiyYar : 5 Median :36.38 Median :49.56 LL_f_603 : 1 KreydyanaDacha : 5 Mean :36.37 Mean :49.66 LL_m_595 : 1 Chernetchina : 4 3rd Qu.:36.80 3rd Qu.:50.04 LLR_f_479: 1 Balakliya : 3 Max. :37.19 Max. :50.21 (Other) :51 (Other) :27 Basin Sex DNA Genotyp L Dnipro: 9 female:31 Min. :13.95 LL : 5 Min. :479.0 Don :48 male :26 1st Qu.:14.91 LLR:11 1st Qu.:564.0 Median :16.13 LR :14 Median :653.0 Mean :18.21 LRR:13 Mean :646.9 3rd Qu.:21.83 RR :14 3rd Qu.:706.0 Max. :22.98 Max. :930.0 Ltc Fm T Dp Min. :186.0 Min. :231.0 Min. :246.0 Min. : 62.00 1st Qu.:200.0 1st Qu.:266.0 1st Qu.:280.0 1st Qu.: 77.00 Median :221.0 Median :316.0 Median :319.0 Median : 91.00 Mean :229.3 Mean :312.7 Mean :318.1 Mean : 90.02 3rd Qu.:255.0 3rd Qu.:341.0 3rd Qu.:356.0 3rd Qu.: 99.00 Max. :338.0 Max. :462.0 Max. :461.0 Max. :139.00 Ci Cs Min. :27.00 Min. :114.0 1st Qu.:32.00 1st Qu.:143.0 Median :37.00 Median :158.0 Mean :37.81 Mean :160.5 3rd Qu.:43.00 3rd Qu.:177.0 Max. :53.00 Max. :240.0 > |
Як ви бачите, у відповідь на цю команду R виводить характеристики кожної змінної. Для факторів вказано кількість значень, що відповідають різним рівням (починаючи з найчисленнішого). Для числових векторів вказано мінімальне та максимальне значення, середнє, медіана та квантилі (ви ж розумієте, що медіана — це другий квантиль, а максимум — четвертий?).
Наостанок зазначимо, що роздивиться фрейм можна й самим простим способом — подивитися на нього цілком. Перш за все, можна просто ввести в редакторі скриптів або в консолі його назву: PE. R виведе у консолі усі дані цього об'єкту (якщо він буде дуже великим — лише частину). Втім, у такому вигляді працювати з фреймом буде не дуже зручно. Краще просто клацнути мишею у вікні Environment по опису об'єкта, що нас цікавить (у нашому випадку — по надпису «57 obs. of 15 variables»; встановіть самі, що буде, якщо обрати назву об'єкта: «PE»!), або, що теж саме, ввести команду View(PE) (рис. 3.6.1).
Рис. 3.6.1. У лівому верхньому куті RStudio відкрито не редактор скриптів, а об'єкт PE
А якщо дані слід не лише роздивлятися, а змінювати? Використайте команду edit(PE) (рис. 3.6.2)!
Рис. 3.6.2. За допомогою функції edit() викликано редактор даних; фрейм даних має в ньому більш-менш звичний вигляд і нагадує лист електронних таблиць
Наведемо ще кілька корисних команд. Команда length(OBJECT) повідомить кількість елементів (компонентів) у об'єкті; ncol(OBJECT) — кількість стовпцов, змінних; nrow(OBJECT) — кількість рядків, випадків; dim(OBJECT) — кількість вимірів, dimensions, тобто і стовпців, і рядків; class(OBJECT) — тип об'єкту, mode(OBJECT) — тип даних (list — у разі даних різних типів), names(OBJECT) — назви частин (наприклад, змінних). Ми вже використовували функцію c, яка поєднує об'єкти у вектор: c(OBJECT1, OBJECT2, ...); cbind(OBJECT1, OBJECT2, ...) поєднує об'єкти у вигляді стовпців, а rbind(OBJECT1, OBJECT2, ...) — рядків. Команда OBJECT виводить у консоль весь об'єкт (або його частину, якщо він дуже великий), head(OBJECT) — виводить першу частину (початок) об'єкту (а, наприклад, head(OBJECT, 3) — перші три рядки), а tail(OBJECT) — його останню частину, кінець. Якщо ви бажаєте проглядати першу частину об'єкту не в консолі, а у більш зручному вікні, можна подати команду View(head(OBJECT)) (зверніть увагу: команда View() починається з великої літери!). Команда ls() виводить у консолі перелік об'єктів, що наявні у робочому оточенні.