Кращі пакети для роботи з даними в R, частина 1

Є два відмінних пакету для роботи з даними в R —
dplyr
та
data.table
. У кожного пакета свої сильні сторони.
dplyr
елегантніше і схожий на природний мову, в той час як
data.table
лаконічний, з його допомогою багато чого можна зробити лише в один рядок. Більш того, в деяких випадках
data.table
швидше (порівняльний аналіз доступний тут), і це може визначити вибір, якщо є обмеження по пам'яті або продуктивності. Порівняння
dplyr
та
data.table
також можна почитати на Stack Overflow, Quora.

Тут можна знайти керівництво і короткий опис
data.table
, тут
dplyr
. Також можна почитати навчальні матеріали
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. Це дані про виплати за позовами державного медичного страхування, їх можна завантажити звідси. Завантажимо дані у форматі JSON за допомогою функції
fromJSON
пакету
jsonlite
. Оскільки JSON — стандартний формат даних для асинхронного взаємодії між браузером і сервером, корисно розібратися в коді нижче, за допомогою якого одержують дані. Введення в роботу з JSON-даними з пакетом
jsonlite
можна знайти на тут і тут. Однак, якщо ви хочете зосередитися тільки на командах
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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.