Датафрейм — это список столбцов
Датафрейм — это таблица R: строки наблюдений, столбцы переменных. Это электронная таблица R и форма, в которой приходят практически все реальные данные: по строке на человека, на измерение, на транзакцию; по столбцу на признак.
Структурно датафрейм — это список векторов одинаковой длины с надстроенным поведением строк и столбцов. Один этот факт объясняет большую часть его правил: у каждого столбца один тип (это вектор), разные столбцы могут иметь разные типы (это список), и все столбцы должны быть одной длины (это и есть «рамка»).
Датафрейм строят, передавая именованные векторы в data.frame():
Текст, числа и логические значения живут бок о бок — такую смесь матрица удержать не может. На практике вы редко будете набирать данные вручную; таблицы обычно приходят через read.csv или из базы данных. Но всё сказанное ниже применимо одинаково, откуда бы датафрейм ни взялся.
Как оценить датафрейм
Никогда не считайте по набору данных, на который вы не посмотрели. Инструментарий осмотра в R невелик, и его стоит довести до автоматизма:
str()запускают первым на любых свежезагруженных данных: по строке на столбец с типом и первыми значениями. Именно здесь вы ловите столбец «чисел», который на самом деле прочитался как character из-за одной затесавшейся записи.nrow()/ncol()дают размеры;names()перечисляет имена столбцов.summary()даёт статистики по столбцам — min/медиана/среднее/max для чисел, количества для логических и факторов.head(df)иtail(df)печатают первые и последние шесть строк — незаменимы, как только реальные наборы становятся слишком большими для полной печати.head()в действии вы увидите ниже на встроенном наборе данных.
Три способа получить столбец
Доступ к столбцу — базовая операция, и R даёт три написания:
people$age— повседневная форма: коротко, читаемо, автодополняется в большинстве редакторов.people[["age"]]— идентичный результат, но имя может прийти из переменной (col <- "age"; people[[col]]), чего$не умеет. Предпочитайте его внутри функций.people[, "age"]— в стиле матриц: строки перед запятой (пусто = все), столбцы после.
Все три возвращают столбец обычным вектором, готовым для mean(people$age). Четвёртое написание в сниппете — это ловушка: people["age"] с одинарными скобками возвращает датафрейм из одного столбца, а не вектор, — то же различие [ и [[, что у списков, потому что датафрейм и есть список. Если математическая функция жалуется, что вход не числовой, проверьте скобки.
Строки и ячейки
Нотация [строка, столбец] достаёт любой срез таблицы:
people[2, ] — вся вторая строка (как датафрейм из одной строки: строки сохраняют рамку, поскольку смешивают типы). people[2, "name"] — одна ячейка. Вектор номеров строк вытаскивает несколько строк.
Последняя строка — самая важная: логическое условие по столбцу выбирает строки, здесь — всех старше 28. Этот шаблон «маскируй строки» — фундамент всей фильтрации данных в R, и он заслуживает отдельной статьи: полный разбор, включая subset() и фильтры по нескольким условиям, — в статье про фильтрацию и выборку.
Добавление и удаление столбцов
Поскольку датафрейм — это список столбцов, столбцы появляются и исчезают обычным присваиванием:
Присваивание новому имени добавляет столбец; вектор должен совпадать с nrow() (или иметь длину 1 — тогда он размножится на все строки). Второе добавление показывает идиоматичный приём: новые столбцы, вычисленные из существующих, с помощью векторной арифметики сразу по всему столбцу. Присваивание NULL полностью удаляет столбец.
Значения столбца перезаписываются точно так же — people$age <- people$age + 1 состарит всех на год.
Встроенные наборы данных и пара слов о тибблах
R поставляется с предзагруженными учебными наборами данных, так что всё вышесказанное можно попробовать, ничего не импортируя. Два, которые встретятся вам в каждом учебнике, — это mtcars (32 машины, 11 числовых переменных) и iris (150 цветков, 4 измерения плюс фактор вида):
head() отрабатывает своё: шесть строк рассказывают о форме данных, не заливая экран. Эти наборы — идеальные площадки: если вы не уверены, как ведёт себя какая-то функция, проверьте её на mtcars, прежде чем направлять на свои данные.
Термин, с которым вы столкнётесь, как только коснётесь tidyverse, — тиббл, версия датафрейма от tidyverse. Та же концепция, более вежливое поведение: печать показывает только первые десять строк с типами столбцов, и нет частичного сопоставления имён. Создаётся через tibble() или возвращается функциями readr/dplyr:
library(tibble)
tibble(name = c("Rosa", "Ken"), age = c(30, 41))
#> # A tibble: 2 x 2
#> name age
#> <chr> <dbl>
#> 1 Rosa 30
#> 2 Ken 41
Всё в этой статье — $, str(), добавление столбцов, логические маски строк — работает на тибблах без изменений. Тиббл и есть датафрейм с дополнительным лоском; выучите датафреймы — и вы выучили оба.
Что вы уносите с собой
- Датафрейм — это список столбцов одинаковой длины: один тип на столбец, смешанные типы по таблице — электронная таблица R.
- Осматривайте до вычислений: сначала
str(), затемhead(),summary(),nrow()/ncol()/names(). df$col,df[["col"]]иdf[, "col"]возвращают столбец вектором;df["col"]с одинарными скобками возвращает датафрейм.df[rows, cols]вырезает что угодно; логическая маска перед запятой фильтрует строки.- Добавляйте столбцы присваиванием (часто вычисляя из других столбцов); удаляйте через
NULL; тренируйтесь наmtcars.
Дальше: пропущенные значения — что означает NA, почему он расползается по вычислениям и как с ним обращаться.
Часто задаваемые вопросы
Как создать датафрейм в R?
Передайте в data.frame() именованные векторы одинаковой длины: df <- data.frame(name = c("Rosa", "Ken"), age = c(30, 41)). Каждый вектор становится столбцом. На практике большинство датафреймов не набирают вручную — они приходят из read.csv() или базы данных, — но структура та же.
Как обратиться к столбцу датафрейма в R?
Тремя способами: df$age (быстро и читаемо), df[["age"]] (тот же результат, работает, когда имя столбца хранится в переменной) и df[, "age"] (в стиле матриц). Все три возвращают столбец обычным вектором. А df["age"] с одинарными скобками возвращает датафрейм из одного столбца — частый источник путаницы.
Что показывает str() для датафрейма?
По строке на столбец: имя, тип и первые несколько значений, а сверху — количество строк и столбцов. Это самый быстрый способ увидеть, прочитался ли столбец как числовой или как текст, — поэтому str() должен быть первым, что вы запускаете на любом только что загруженном наборе данных.
Как добавить столбец в датафрейм в R?
Присвойте значение ещё не существующему имени: df$score <- c(88, 75, 93). Вектор должен совпадать по числу строк (или быть длины 1, тогда он размножится на все строки). Удалите столбец, присвоив NULL: df$score <- NULL.