Редактирование таблиц данных в R

Редактирование таблиц в RВ прошлый раз мы говорили о том, как загрузить данные в среду R. Следующим важным этапом является их подготовка к визуализации и статистическому анализу. Для этого нам, как правило, необходимо внести некоторые изменения в таблицу, например: удалить столбец или строку, переименовать колонку, произвести сортировку или фильтрацию данных. Многие из этих операций можно сделать в Excel. Однако, зачастую возникают ситуации, когда необходимо изменить структуру или содержание таблицы прямо в ходе анализа. И вот тут у начинающих пользователей R могут возникнуть проблемы. В этой статье мы научимся их решать.


Структура таблицы и изменение типов данных

Лучший способ для закрепления новых знаний - это практика. Поэтому мы продолжим работать с таблицей физических данных студентов одного из военных вузов "voenvuz". Итак, загрузим знакомую уже нам таблицу в Rgui (таблицу можно скачать здесь).

Функции head и str

Для того, чтобы посмотреть правильно ли загрузились данные, введем команду head(voenvuz), которая покажет первые 6 строчек нашей таблицы. Если все загрузилось нормально, то переходим к команде str(voenvuz), которая выведет в консоль структуру таблицы.Функция str RИтак, в поле "data.frame" мы видим, что наша таблица состоит из 20 строк и 6 столбцов. Под ним располагается список названий столбцов, тип данных и первые шесть элементов каждого столбца. Обратите внимание, что колонки "Name" и "Rhesus.factor" сейчас хранят в себе категориальный тип данных (Factor), а остальные - целочисленный. Компьютер вычислил это автоматически, но в нашем случае - вычислил неверно. Прежде чем мы исправим типы этих данных, немного теоретической информации.

О типах данных

Почему важно правильно распознать тип данных в столбцах таблицы? Потому что при проведении статистических тестов, информация о типе данных учитывается и влияет на результат.

В языке R можно выделить 5 основных типов данных, хранящихся в столбцах таблицы:

  • числовой (numeric);
  • целочисленный (integer);
  • текстовый (character);
  • категориальный (Factor);
  • логический (logical).

Есть также комплексный (complex) и сырой (raw) типы данных, но они редко встречаются, и поэтому я о них здесь писать не буду. Пропущенные данные обозначаются как "NA" (от англ. not available - недоступно), и тогда R игнорирует их.

Изменим типы данных на практике

Посмотрим еще раз на таблицу. Логично предположить, что столбец "Name" с именами студентов не содержит никаких категорий, поэтому, преобразуем эту колонку в обычный текстовый тип данных:
voenvuz$Name <- as.character(voenvuz$Name) 

Идем дальше, столбец "Age" был правильно идентифицирован как целочисленный. А вот столбцы "Height" и "Weight" являются скорее числовыми, т.к. могут содержать промежуточные значения, например 182.5. Переделаем их из типа Integer в тип Numeric:
voenvuz$Height <- as.numeric(voenvuz$Height) 
voenvuz$Weight <- as.numeric(voenvuz$Weight) 

Последнее, что нам нужно - это изменить тип данных в столбце "Blood.group". Каждый из студентов так или иначе имеет одну из 4 групп крови, соответственно, этот столбец содержит четыре категории: "1", "2", "3", "4". Другими словами, в нем должен находиться категориальный тип данных:
voenvuz$Blood.group <- as.factor(voenvuz$Blood.group)

В итоге, повторив команду str(voenvuz), мы должны получить вот такую картинку.
Меняем тип данных в R


Редактирование элементов таблицы

Иногда возникают ситуации, когда необходимо вставить в таблицу столбец или строку, изменить значение элемента или название колонки. Наша таблица - не исключение и нуждается в доработке.

Добавление строк

Добавим в таблицу данные о двух новых студентах: Иване и Олеге. Для этого необходимо создать новую структуру - список (list), В список мы по порядку вносим параметры, совпадающие со структурой таблицы (напомню, что в кавычках мы пишем нечисловые типы данных):
Ivan <- list("Ivan", 21, 175, 67, "2", "+")
Oleg <- list("Oleg", 24, 189, 82, "1", "+")

После, при помощи функции rbind (от англ. row bind, что дословно означает "связать строчки") мы объединим эти два списка с нашей таблицей:
voenvuz <- rbind(voenvuz, Ivan, Oleg)

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

Теперь у нас в таблице два Ивана и два Олега. В данном случае хорошо было бы прописать для каждого студента свой идентификационный номер (ID), чтобы не запутаться, кто есть кто. Для этого создадим структуру, которая называется вектор (последовательность элементов одного типа). В него мы запишем последовательность от 1 до 22, так, чтобы у каждого из наших 22 студентов был свой уникальный ID:
ID <- c(1:22)
Теперь объединим наш вектор с таблицей, воспользовавшись функцией cbind (от англ. column bind):
voenvuz <- cbind(voenvuz, ID)
Не забудьте поменять тип данных нового столбца на символьный:
voenvuz$ID <- as.character(voenvuz$ID)

В качестве еще одного примера добавления новых столбцов с данными в таблицу, рассчитаем индекс массы тела (BMI) для каждого студента. Для этого, мы воспользуемся новым способом: напишем математическую формулу индекса на языке R и присвоим ей новое имя столбца "BMI" внутри нашей таблицы:
voenvuz$BMI <- voenvuz$Weight / (voenvuz$Height * 0.01)^2

Проверьте, что получилось, используя уже знакомые нам функции head и str

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

Существует относительно "универсальная формула" для удаления элементов таблицы: new.data <- my.data[ , ]
Для того, чтобы корректно ее использовать необходимо запомнить несколько правил:

  1. После имени таблицы пространство внутри квадратных скобок следует разделить на две части запятой.
  2. Все, что находится до запятой, относится к строчкам, все что после - к столбцам.
  3. Поставьте минус перед номером столбца или номером строки, которую собираетесь удалить.
  4. Если таких элементов несколько, используйте функцию c(...): внутри скобок перечисление элементов через запятую.

В нашем случае, удалять из таблицы ничего не надо, но я покажу пару примеров, назвав "укороченные" таблицы именами "trash1", "trash2", "trash3", "trash4":
trash1 <- voenvuz[ , -7]    # удалим раннее созданный столбец "ID"
trash2 <- voenvuz[ -2, ]    # удалим строку под номером 2 (данные Петра)
trash3 <- voenvuz[ -c(1,2,3,4,5,6,7,8,9,10), ]   # удалим первые десять строк
trash4 <- voenvuz[ -c(1:10), ]   # то же самое, только код короче

Изменение имен столбцов и  данных в ячейках:

Переименуем колонку "Rhesus.factor" на укороченное "Rhesus". Для этого нужно вызвать функцию names, написать в параметрах функции имя таблицы и номер столбца, и присвоить ему новое имя:
names(voenvuz)[6] <- "Rhesus"

Изменение данные в ячейках таблицы не представляет особой сложности. В квадратных скобках прописываем координаты нужной ячейки (до запятой - строка, после запятой - столбец) и присваиваем новое значение:
voenvuz[1, "Name"] <- "Vanya" 

После всех наших манипуляций мы должны получить вот такую таблицу данных:
Редактируем таблицу в R


Фильтрация и сортировка данных

В качестве примера, исключим из таблицы данных студентов, чей возраст больше 23 лет. Существует множество способов решения подобного рода задач, включая циклы if-else, for или while (о них будет написана отдельная статья). Однако в нашем случае хватит простого фильтра, основанного на логическом операторе "<=" (меньше или равно). В квадратных скобках таблицы находится объект таблицы, по которому будет проводиться фильтрация:
voenvuz.final <- voenvuz[voenvuz$Age <= 23, ]

Того же результата мы добьемся, если будем использовать логические операторы ">" (больше) и "!" (исключить):
voenvuz.final <- voenvuz[!voenvuz$Age > 23, ]

Итак, мы получили финальную версию таблицы "voenvuz.final". Осталось лишь упорядочить столбцы:
voenvuz.final <- voenvuz.final[,c("Name", "ID", "Age", "Height", "Weight", "BMI", "Blood.group", "Rhesus")]

И произвести сортировку данных по имени студентов, используя функцию order:
voenvuz.final <- voenvuz.final[order(voenvuz.final$Name),]

После завершения редактирования таблицы, обновим имена строк, т.к. сейчас они не соответствуют действительности, и выведем таблицу на экран, введя имя таблицы в консоль:
rownames(voenvuz.final) = c(1:length(voenvuz.final$ID))
voenvuz.final
Результат обработки данных R


Заключение

Описанные выше способы редактирования данных в таблице не уникальны, существует множество других методов и команд, позволяющих получить желаемый результат. Я рассказал лишь о наиболее простых и часто используемых. Для более детального ознакомления с этой темой я хотел бы порекомендовать два источника на английском языке:

  1. сайт http://stackoverflow.com/ (уже подробно разобраны тысячи вопросов по этой теме)
  2. книгу-справочник "R book" by Michael J. Crawley (легко найти бесплатную PDF версию в интернете).

Если у Вас возникли вопросы или проблемы с редактированием таблиц данных, Вы всегда можете оставить комментарий под этой статьей, и он не останется без внимания. А в качестве продолжения, читайте следующую статью, посвященную сохранению данных в среде R.

Комментарии: 13
  1. Алексей

    здравствуйте,
    что делать в случае, если таблицы загружаются корректно (на примере csv, разделитель ; , header = true) — выводит полную таблицу с наименованием заголовков, но команды анализа не проходят — ни head, ни summary, ни какие-либо еще:
    > head(«Test1.txt»)
    [1] «Test1.txt»
    или
    > summary(«Test1.csv»)
    Length Class Mode
    1 character character
    Если писать без кавычек, оно файл вообще не видит.

    1. Алексей

      Небольшая поправка: R-commander csv (и другие форматы) ест, а само R-studio даже принимает некоторые команды, которые копируются из коммандера. Но напрямую работать с таблицей данных не хочет. Например:
      with(Dataset, Hist(mmm, scale=»percent», breaks=»Sturges», col=»red», xlab=»Кгчт», ylab=»Доля», main=»»)) (mmm — это столбец) — выдает что надо, гистограмму с измененным цветом, а на это:
      Hist(`Test1.csv$M`, scale=»percent», breaks=»Sturges», col=»red», xlab=»Кгчт», ylab=»Доля», main=»»)
      ругается:
      Error in hist.default(x, axes = FALSE, xlab = xlab, ylab = ylab, main = main, :
      invalid number of ‘breaks’
      Т.е. например, через коммандер я могу ввести таблицу и построить гистограмму, а без его использования почему-то не выходит — программа отказывается работать с данными.

      1. Samoedd (Автор записи)
        https://samoedd.com

        Здравствуйте, Алексей. Я Rcmdr не пользовался, поэтому не знаю как команды копируются оттуда.
        Скиньте пожалуйста ссылку на Ваш файл и напишите код, с помощью которой Вы загружаете таблицу в Rstudio. Также рекомендую посмотреть как я загружал данные тут: https://samoedd.com/soft/r-import

      2. Алексей

        Добрый вечер.
        Файл тут — https://yadi.sk/i/giBeNDQkTEF4pw
        Команды:
        read.csv(«Test1.csv», sep = «;», header = TRUE)
        str(«Test1.csv»)
        head(«Test1.csv»)
        summary(‘Test1.csv$M’)

        Путь к файлу не прописан, т.к. он лежит в заранее определенной директории
        После команды read.csv программа показывает ряд данных — 130 строк. Разделитель ; более корректен, т.к. с разделителем , столбцы отдельно не воспринимаются.
        Остальные команды — попытки протестировать, как программа восприняла файл.
        з.ы. файлы загружал в соответствии с Вашей инструкцией

      3. Samoedd (Автор записи)
        https://samoedd.com

        Все, понял. При загрузке данных Вы забыли присвоить ей имя: в R она загрузилась, ее содержание отобразилось в консоли, но она но не сохранилась в виде переменной, т.е. R ее не «запомнил». Чтобы R сохранил таблицу у себя в памяти, дайте ей имя и после этого можно будет проводить операции с ней.

        Рассмотрим на конкретно Вашем примере. Допустим, Вы решили назвать Вашу таблицу mydata (советую выбирать названия покороче, ускоряет работу в R):

        mydata < - read.csv(«Test1.csv», sep = «;», header = TRUE)
        str(mydata)
        head(mydata)
        summary(mydata$M)

        Рад помочь Вам в освоении языка R. Если возникнут вопросы или сложности, всегда обращайтесь!
        С уважением, Сергей

  2. Александр

    Добрый всем вечер! Помогите, пожалуйста, кому не сложно, решить мою проблемку в R. Я не знаю r совсем, но есть желание научиться, но есть необходимость в таблице, которую я импортирую в r, оставить только повторяющиеся строки. Т.е. есть строки в столбце с повторениями, таких повторений может быть по 10 штук в 1 таблице. Как сделать так, чтобы в таблице остались только повторяющиеся строки? Например есть строки
    1431
    7777
    1431
    1431
    , нужно чтобы осталось только 1431 одна строка.

    1. Samoedd (Автор записи)
      https://samoedd.com

      Здравствуйте, Александр! Вашу проблему можно решить таким способом:

      new.df < - df[!duplicated(df$value),]

      где df — это имя Вашей таблицы, new.df — имя новой таблицы, value — имя столбца, содержащего повторяющиеся значения. Важно отметить, что такой метод будет извлекать только впервые повстречавшиеся значения в столбце вместе со всей строкой, игнорируя строки с повторяющимися значениями.

  3. Владимир

    Здравствуйте, а если мне нужно данные из одного столбика разбить на несколько? Допустим, в одном столбике в ячейках есть текстовая информация про то, есть ли в квартире wi-fi, телевизор или кондиционер, как разбить этот столбик на три, где в одном будут значения 1 или 0 для wi-fi, во втором 1 или 0 для телевизора и в третьем 1 или 0 для интернета, соотвественно изначальный столбик такого вида:

    Удобства_в_квартире
    1 Wi-fi,телевизор
    2 Wi-fi
    3 Na
    4 Na
    5 Кондиционер
    6 Wi-fi, кондиционер

    1. Samoedd
      https://samoedd.com

      Здравствуйте, Владимир!

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

      1) если позиций немного, то разделите этот столбик на три, и вручную вбейте данные в таблицу (как, собственно, Вы сами описали)
      2) если у Вас тысячи позиций, воспользуйтесь одним из ответов на этой страничке: https://stackoverflow.com/questions/4350440/split-a-column-of-a-data-frame-to-multiple-columns

  4. Юрий

    Просто недавно открыл для себя язык R и Rstudio. Для новичка посоветовали Ваш сайт. Ваши статьи помогли в первых шагах, спасибо)

    1. Samoedd (Автор записи)
      https://samoedd.com

      Вам спасибо, что читаете:-)

  5. Юрий

    Таблица же называется voenvuz_clean? По крайне мере скачанная по ссылке.

    1. Samoedd (Автор записи)
      https://samoedd.com

      Здравствуйте, Юрий! Да, voenvuz_clean. При загрузке таблицы в R не забудьте добавить к имени расширение .xlsx.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *