- PVSM.RU - https://www.pvsm.ru -

Лучшие пакеты для работы с данными в R, часть 1

Есть два отличных пакета для работы с данными в R — dplyr и data.table. У каждого пакета свои сильные стороны. dplyr элегантнее и похож на естественный язык, в то время как data.table лаконичный, с его помощью многое можно сделать всего в одну строку. Более того, в некоторых случаях data.table быстрее (сравнительный анализ доступен здесь [1]), и это может определить выбор, если есть ограничения по памяти или производительности. Сравнение dplyr и data.table можно также почитать на Stack Overflow [2] и Quora [3].

Здесь [4] можно найти руководство и краткое описание data.table, а здесь [5] — для dplyr. Также можно почитать обучающие материалы [6] по dplyr на DataScience+.

Контекст

Я уже долго использую dplyr и data.table для работы с данными. Если кто-то знаком только с одним из пакетов, возможно, будет полезно посмотреть на код, выполняющий одно и то же, в обоих, чтобы изучить второй.

dplyr

В dplyr есть пять глаголов, предназначенных для выполнения большинства операций по работе с данными. Select — для выбора одного или более столбцов. Filter — для выбора строк на основании каких-либо критериев. Arrange — для сортировки данных по одному или нескольким столбцам по возрастанию или убыванию. Mutate — для добавления к данным новых столбцов. Summarise — для выделения части данных.

data.table

У data.table очень короткий общий формат — DT[i, j, by], который можно интерпретировать так: возьмите DT, выберите строки, используя i, и вычислите j, сгруппировав по by.

Работа с данными

Сначала установим некоторые пакеты для нашего проекта.

library(dplyr)
library(data.table)
library(lubridate)
library(jsonlite)
library(tidyr)
library(ggplot2)
library(compare)

Будем использовать данные из DATA.GOV [7]. Это данные о выплатах по искам государственного медицинского страхования, их можно загрузить отсюда [8]. Загрузим данные в формате JSON с помощью функции fromJSON пакета jsonlite. Поскольку JSON — стандартный формат данных для асинхронного взаимодействия между браузером и сервером, полезно разобраться в коде ниже, с помощью которого получают данные. Введение в работу с JSON-данными с пакетом jsonlite можно найти здесь [9] и здесь [10]. Однако, если вы хотите сосредоточиться только на командах dplyr и data.table, можно спокойно запустить код ниже в двух разных окнах и не вникать в подробности.

spending=fromJSON("https://data.medicare.gov/api/views/nrth-mfg3/rows.json?accessType=DOWNLOAD")
names(spending)

"meta" "data" 

meta=spending$meta
hospital_spending=data.frame(spending$data)
colnames(hospital_spending)=make.names(meta$view$columns$name)
hospital_spending=select(hospital_spending,-c(sid:meta))

glimpse(hospital_spending)

Observations: 70598
Variables:
$ Hospital.Name                       (fctr) SOUTHEAST ALABAMA MEDICAL CENT...
$ Provider.Number.                    (fctr) 010001, 010001, 010001, 010001...
$ State                               (fctr) AL, AL, AL, AL, AL, AL, AL, AL...
$ Period                              (fctr) 1 to 3 days Prior to Index Hos...
$ Claim.Type                          (fctr) Home Health Agency, Hospice, I...
$ Avg.Spending.Per.Episode..Hospital. (fctr) 12, 1, 6, 160, 1, 6, 462, 0, 0...
$ Avg.Spending.Per.Episode..State.    (fctr) 14, 1, 6, 85, 2, 9, 492, 0, 0,...
$ Avg.Spending.Per.Episode..Nation.   (fctr) 13, 1, 5, 117, 2, 9, 532, 0, 0...
$ Percent.of.Spending..Hospital.      (fctr) 0.06, 0.01, 0.03, 0.84, 0.01, ...
$ Percent.of.Spending..State.         (fctr) 0.07, 0.01, 0.03, 0.46, 0.01, ...
$ Percent.of.Spending..Nation.        (fctr) 0.07, 0.00, 0.03, 0.58, 0.01, ...
$ Measure.Start.Date                  (fctr) 2014-01-01T00:00:00, 2014-01-0...
$ Measure.End.Date                    (fctr) 2014-12-31T00:00:00, 2014-12-3...

Как показано выше, все столбцы импортированы как факторные переменные. Давайте сделаем числовые данные числами.

cols = 6:11; # Это столбцы, которые надо сделать числовыми
hospital_spending[,cols] <- lapply(hospital_spending[,cols], as.numeric)

Последние два столбца указывают начало и конец измерения. Давайте используем пакет lubridate, чтобы исправить их.

cols = 12:13; # Эти столбцы надо заменить на даты
hospital_spending[,cols] <- lapply(hospital_spending[,cols], ymd_hms)

Теперь давайте убедимся, что столбцы имеют правильный тип.

sapply(hospital_spending, class)

$Hospital.Name
    "factor"
$Provider.Number.
    "factor"
$State
    "factor"
$Period
    "factor"
$Claim.Type
    "factor"
$Avg.Spending.Per.Episode..Hospital.
    "numeric"
$Avg.Spending.Per.Episode..State.
    "numeric"
$Avg.Spending.Per.Episode..Nation.
    "numeric"
$Percent.of.Spending..Hospital.
    "numeric"
$Percent.of.Spending..State.
    "numeric"
$Percent.of.Spending..Nation.
    "numeric"
$Measure.Start.Date
        "POSIXct" "POSIXt" 
$Measure.End.Date
        "POSIXct" "POSIXt" 

Создать таблицу с данными

Можно создать таблицу с данными (data.table) с помощью функции data.table():

hospital_spending_DT = data.table(hospital_spending)
class(hospital_spending_DT)

"data.table" "data.frame"

Выбрать некоторые столбцы

Чтобы выбрать столбцы в dplyr, используем глагол select. В data.table, в свою очередь, можно задать имена столбцов.

Выбор одной переменной

Выберем переменную «Hospital Name».

from_dplyr = select(hospital_spending, Hospital.Name)
from_data_table = hospital_spending_DT[,.(Hospital.Name)]

Теперь нужно убедиться, что результаты dplyr и data.table одинаковы.

compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

Удаление одной переменной

from_dplyr = select(hospital_spending, -Hospital.Name)
from_data_table = hospital_spending_DT[,!c("Hospital.Name"),with=FALSE]
compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

Также можно взять функцию :=, изменяющую входную таблицу данных (data.table) по ссылке.
Используем и функцию copy(), создающую копию исходного объекта, т.е. любая следующая операция над данными по ссылке на копию не затронет начальный объект.

DT=copy(hospital_spending_DT)
DT=DT[,Hospital.Name:=NULL]
"Hospital.Name"%in%names(DT)
FALSE

Аналогично можно одновременно удалить несколько переменных:

DT=copy(hospital_spending_DT)
DT=DT[,c("Hospital.Name","State","Measure.Start.Date","Measure.End.Date"):=NULL]
c("Hospital.Name","State","Measure.Start.Date","Measure.End.Date")%in%names(DT)

FALSE FALSE FALSE FALSE 

Выбор нескольких переменных

Давайте выберем переменные Hospital.Name, State, Measure.Start.Date и Measure.End.Date.

from_dplyr = select(hospital_spending, Hospital.Name,State,Measure.Start.Date,Measure.End.Date)
from_data_table = hospital_spending_DT[,.(Hospital.Name,State,Measure.Start.Date,Measure.End.Date)]
compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

Удаление нескольких переменных

Давайте теперь удалим переменные Hospital.Name, State, Measure.Start.Date и Measure.End.Date из исходного набора данных hospital_spending и таблицы данных (data.table) hospital_spending_DT.

from_dplyr = select(hospital_spending, -c(Hospital.Name,State,Measure.Start.Date,Measure.End.Date))
from_data_table = hospital_spending_DT[,!c("Hospital.Name","State","Measure.Start.Date","Measure.End.Date"),with=FALSE]
compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

В dplyr есть функции contains(), starts_with() и ends_with(), которые можно использовать с глаголом select. В data.table разрешены регулярные выражения. В качестве примера выберем столбцы, содержащие в имени слово «Date».

from_dplyr = select(hospital_spending,contains("Date"))
from_data_table = subset(hospital_spending_DT,select=grep("Date",names(hospital_spending_DT)))
compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

names(from_dplyr)

"Measure.Start.Date" "Measure.End.Date" 

Переименовать столбцы

setnames(hospital_spending_DT,c("Hospital.Name", "Measure.Start.Date","Measure.End.Date"), c("Hospital","Start_Date","End_Date"))
names(hospital_spending_DT)

"Hospital" "Provider.Number." "State" "Period" "Claim.Type" "Avg.Spending.Per.Episode..Hospital." "Avg.Spending.Per.Episode..State." "Avg.Spending.Per.Episode..Nation." "Percent.of.Spending..Hospital." "Percent.of.Spending..State." "Percent.of.Spending..Nation." "Start_Date" "End_Date" 

hospital_spending = rename(hospital_spending,Hospital= Hospital.Name, Start_Date=Measure.Start.Date,End_Date=Measure.End.Date)
compare(hospital_spending,hospital_spending_DT, allowAll=TRUE)

TRUE
  dropped attributes

Автор: Инфопульс Украина

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/data-mining/123602

Ссылки в тексте:

[1] здесь: https://github.com/Rdatatable/data.table/wiki/Benchmarks-%3A-Grouping

[2] Stack Overflow: http://stackoverflow.com/questions/21435339/data-table-vs-dplyr-can-one-do-something-well-the-other-cant-or-does-poorly

[3] Quora: https://www.quora.com/Which-is-better-to-use-for-data-manipulation-dplyr-package-or-data-table-library

[4] Здесь: https://cran.r-project.org/web/packages/data.table/index.html

[5] здесь: https://cran.r-project.org/web/packages/dplyr/index.html

[6] обучающие материалы: http://datascienceplus.com/data-manipulation-with-dplyr/

[7] DATA.GOV: https://www.data.gov/

[8] отсюда: https://catalog.data.gov/dataset/medicare-hospital-spending-by-claim-61b57

[9] здесь: https://cran.r-project.org/web/packages/jsonlite/vignettes/json-aaquickstart.html

[10] здесь: http://datascienceplus.com/introduction-to-time-series-with-json-data/

[11] Источник: https://habrahabr.ru/post/301914/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best