Добавление столбца: df$new <- value
Чтобы добавить столбец в базовом R, присвойте значение имени, которого ещё нет. Значение обычно вычисляется из существующих столбцов:
Произошло две вещи. orders$total получил полный вектор — price * qty вычисляется для всех строк сразу, потому что арифметика в R векторизована. orders$currency получил одиночное значение, которое R растиражировал на все четыре строки. Любая другая длина — ошибка (replacement has 3 rows, data has 4): так R защищает вас от рассинхронизированного столбца.
Это работает потому, что датафрейм — это список столбцов равной длины: присваивание нового именованного элемента наращивает список. Эта модель разобрана в статье про датафреймы.
Условные столбцы: ifelse()
Столбцу, значение которого зависит от условия, нужен ifelse() — векторизованный родственник if. Он принимает целый вектор условий и возвращает значение для каждой строки:
Почему не обычный if? Потому что if вычисляет ровно одно TRUE/FALSE — получив столбец, он выдаёт ошибку (the condition has length > 1). ifelse(test, yes, no) проверяет каждый элемент и выбирает построчно. Для трёх и более исходов можно вкладывать:
Вложенность в два уровня — нормально; три и больше превращаются в пирамиду — ровно для этой работы и создан case_when() из dplyr (ниже). Сам одиночный if/else разобран в статье про if-else.
Несколько столбцов сразу: transform()
transform() из базового R добавляет несколько столбцов одним вызовом, с голыми именами столбцов:
Обратите внимание: transform() возвращает новый датафрейм — результат нужно присвоить обратно, тогда как df$new <- ... изменяет на месте. Одно ограничение: выражения внутри одного вызова transform() не видят друг друга, поэтому discount = ifelse(total > 50, ...) там не сработает (total ещё не существует). Делайте в два шага — или через mutate(), который это разрешает.
Изменение против создания
Тот же синтаксис присваивания перезаписывает существующий столбец — единственная разница в том, существовал ли столбец раньше:
На этом стоит задержаться: R никак не предупреждает, когда вы перезаписываете столбец. Опечатка вроде df$prise <- round(df$price, 2) молча создаёт новый столбец вместо исправления старого. После преобразования выведите датафрейм через print() или str() и убедитесь, что изменили именно то, что хотели.
Удаление столбца
Присвойте NULL, чтобы удалить:
Столбец исчез, без церемоний. Чтобы удалить несколько, df[, c("a", "b")] (оставить перечисленное) обычно понятнее, чем повторяющиеся NULL.
Способ dplyr: mutate()
Глагол dplyr для всего перечисленного — mutate(). Сниппеты ниже статичны — песочница выполняет только базовый R, — но вот как выглядят те же операции:
library(dplyr)
orders |>
mutate(
total = price * qty,
big = total > 50 # can use total, defined one line up
)
Два преимущества перед базовым R. Во-первых, столбцы, определённые в одном mutate(), могут ссылаться друг на друга по порядку — то, в чём отказывает transform(). Во-вторых, условные помощники лучше вложенных ifelse():
students |>
mutate(
grade = if_else(score >= 60, "pass", "fail"),
band = case_when(
score >= 85 ~ "high",
score >= 60 ~ "mid",
.default = "low"
)
)
if_else() — более строгий ifelse() (обе ветки должны быть одного типа — ловит настоящие баги). case_when() читается как плоский список пар условие ~ значение, проверяемых сверху вниз, с .default в качестве запасного варианта — читаемая замена пирамиды из ifelse(). Как и каждый глагол dplyr, mutate() возвращает новый датафрейм; как он сцепляется с остальными, показывает введение в dplyr.
Что вы уносите с собой
df$new <- выражениедобавляет столбец; выражение выполняется для всех строк сразу.ifelse(test, yes, no)строит условные столбцы; обычныйif— нет.transform()добавляет несколько столбцов за вызов, но они не видят друг друга;mutate()— видят.- То же присваивание молча перезаписывает — проверяйте орфографию после преобразования.
df$col <- NULLудаляет столбец;case_when()заменяет пирамиды вложенныхifelse().
Дальше: переименование столбцов — names(), надёжная базовая идиома и rename() из dplyr.
Часто задаваемые вопросы
Как добавить новый столбец в датафрейм в R?
Присвойте значение имени столбца, которого ещё нет: df$total <- df$price * df$qty. R создаст столбец на месте. Значением может быть одиночное значение (растиражированное на все строки) или вектор, вычисленный из других столбцов, — лишь бы его длина совпадала с числом строк.
Как создать условный столбец в R?
Используйте векторизованный ifelse(): df$grade <- ifelse(df$score >= 60, "pass", "fail") проверяет все строки сразу. Не используйте обычный if — он обрабатывает одно условие, а не столбец. Для более чем двух исходов вкладывайте вызовы ifelse() или используйте case_when() из dplyr.
Что делает mutate() в R?
mutate() — глагол dplyr для добавления и преобразования столбцов: df |> mutate(total = price * qty) возвращает копию датафрейма с новым столбцом. Он может определить несколько столбцов за один вызов, причём последующие столбцы могут использовать предыдущие, определённые в том же mutate.
Как удалить столбец из датафрейма в R?
Присвойте ему NULL: df$notes <- NULL удаляет столбец на месте. В dplyr select(-notes) возвращает копию без него.