data.table
Вычисление итоговой статистики
Поиск…
замечания
Напоминание: синтаксис DT[where, select|update|do, by]
используется для работы с столбцами таблицы данных.
- Часть «где» является аргументом
i
- Часть «select | update | do» является аргументом
j
Эти два аргумента обычно передаются положением вместо имени.
Подсчет строк по группам
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
Использование .N
.N
в j
хранит количество строк в подмножестве. При изучении данных, .N
удобно ...
подсчитывать строки в группе,
DT[Species == "setosa", .N] # 50
или подсчитывать строки во всех группах,
DT[, .N, by=.(Species, Bin)] # Species Bin N # 1: setosa (4,6] 50 # 2: versicolor (6,8] 20 # 3: versicolor (4,6] 30 # 4: virginica (6,8] 41 # 5: virginica (4,6] 9
или найдите группы, которые имеют определенное количество строк.
DT[, .N, by=.(Species, Bin)][ N < 25 ] # Species Bin N # 1: versicolor (6,8] 20 # 2: virginica (4,6] 9
Обработка отсутствующих групп
Однако у нас отсутствуют группы с нулевым числом. Если они имеют значение, мы можем использовать table
из базы:
DT[, data.table(table(Species, Bin))][ N < 25 ]
# Species Bin N
# 1: virginica (4,6] 9
# 2: setosa (6,8] 0
# 3: versicolor (6,8] 20
В качестве альтернативы мы можем присоединиться ко всем группам:
DT[CJ(Species=Species, Bin=Bin, unique=TRUE), on=c("Species","Bin"), .N, by=.EACHI][N < 25]
# Species Bin N
# 1: setosa (6,8] 0
# 2: versicolor (6,8] 20
# 3: virginica (4,6] 9
Примечание к .N
:
- В этом примере используется
.N
вj
, где оно относится к размеру подмножества. - В
i
это относится к общему количеству строк.
Пользовательские сводки
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
Предположим, мы хотим, чтобы summary
функция выводилась для Sepal.Length
вместе с количеством наблюдений:
DT[, c(
as.list(summary(Sepal.Length)),
N = .N
), by=.(Species, Bin)]
# Species Bin Min. 1st Qu. Median Mean 3rd Qu. Max. N
# 1: setosa (4,6] 4.3 4.8 5.0 5.006 5.2 5.8 50
# 2: versicolor (6,8] 6.1 6.2 6.4 6.450 6.7 7.0 20
# 3: versicolor (4,6] 4.9 5.5 5.6 5.593 5.8 6.0 30
# 4: virginica (6,8] 6.1 6.4 6.7 6.778 7.2 7.9 41
# 5: virginica (4,6] 4.9 5.7 5.8 5.722 5.9 6.0 9
Мы должны сделать j
список столбцов. Обычно некоторые играют с c
, as.list
и .
достаточно, чтобы выяснить правильный способ продолжения.
Назначение сводной статистики в качестве новых столбцов
Вместо создания сводной таблицы мы можем захотеть сохранить итоговую статистику в новом столбце. Мы можем использовать :=
как обычно. Например,
DT[, is_big := .N >= 25, by=.(Species, Bin)]
Ловушки
Неверные данные
Если вы обнаружите, что хотите разобрать имена столбцов, например
Возьмите среднее значение
x.Length/x.Width
гдеx
принимает десять различных значений.
то вы, вероятно, смотрите на данные, вложенные в имена столбцов, что является плохой идеей. Читайте о аккуратных данных и затем переформатируйте в длинный формат.
Краткие сводки
Кадры данных и data.tables хорошо разработаны для табличных данных, где строки соответствуют наблюдениям и столбцам для переменных. Если вы обнаружите, что хотите суммировать по строкам, например
Найти стандартное отклонение по столбцам для каждой строки.
то вам, вероятно, следует использовать матрицу или какой-либо другой формат данных.
Сводная функция
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
summary
полезно для просмотра сводной статистики. Помимо прямого использования, такого как summary(DT)
, его также можно применять для каждой группы с помощью split
:
lapply(split(DT, by=c("Species", "Bin"), drop=TRUE, keep.by=FALSE), summary)
# $`setosa.(4,6]`
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100
# 1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200
# Median :5.000 Median :3.400 Median :1.500 Median :0.200
# Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246
# 3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300
# Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600
#
# $`versicolor.(6,8]`
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# Min. :6.10 Min. :2.20 Min. :4.000 Min. :1.20
# 1st Qu.:6.20 1st Qu.:2.80 1st Qu.:4.400 1st Qu.:1.30
# Median :6.40 Median :2.90 Median :4.600 Median :1.40
# Mean :6.45 Mean :2.89 Mean :4.585 Mean :1.42
# 3rd Qu.:6.70 3rd Qu.:3.10 3rd Qu.:4.700 3rd Qu.:1.50
# Max. :7.00 Max. :3.30 Max. :5.000 Max. :1.70
#
# [...results truncated...]
Чтобы включить группы с нулевым числом, установите drop=FALSE
в split
.
Применение функции суммирования к нескольким переменным
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
Чтобы применить ту же функцию суммирования к каждому столбцу по группе, мы можем использовать lapply
и .SD
DT[, lapply(.SD, median), by=.(Species, Bin)]
# Species Bin Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1: setosa (4,6] 5.0 3.4 1.50 0.2
# 2: versicolor (6,8] 6.4 2.9 4.60 1.4
# 3: versicolor (4,6] 5.6 2.7 4.05 1.3
# 4: virginica (6,8] 6.7 3.0 5.60 2.1
# 5: virginica (4,6] 5.8 2.7 5.00 1.9
Мы можем фильтровать столбцы в .SD
с аргументом .SDcols
:
DT[, lapply(.SD, median), by=.(Species, Bin), .SDcols="Petal.Length"]
# Species Bin Petal.Length
# 1: setosa (4,6] 1.50
# 2: versicolor (6,8] 4.60
# 3: versicolor (4,6] 4.05
# 4: virginica (6,8] 5.60
# 5: virginica (4,6] 5.00
Множественные функции суммирования
В настоящее время простейшим расширением для нескольких функций является, возможно:
DT[, unlist(recursive=FALSE, lapply(
.(med = median, iqr = IQR),
function(f) lapply(.SD, f)
)), by=.(Species, Bin), .SDcols=Petal.Length:Petal.Width]
# Species Bin med.Petal.Length med.Petal.Width iqr.Petal.Length iqr.Petal.Width
# 1: setosa (4,6] 1.50 0.2 0.175 0.100
# 2: versicolor (6,8] 4.60 1.4 0.300 0.200
# 3: versicolor (4,6] 4.05 1.3 0.525 0.275
# 4: virginica (6,8] 5.60 2.1 0.700 0.500
# 5: virginica (4,6] 5.00 1.9 0.200 0.200
Если вы хотите, чтобы имена были как Petal.Length.med
вместо med.Petal.Length
, измените порядок:
DT[, unlist(recursive=FALSE, lapply(
.SD,
function(x) lapply(.(med = median, iqr = IQR), function(f) f(x))
)), by=.(Species, Bin), .SDcols=Petal.Length:Petal.Width]
# Species Bin Petal.Length.med Petal.Length.iqr Petal.Width.med Petal.Width.iqr
# 1: setosa (4,6] 1.50 0.175 0.2 0.100
# 2: versicolor (6,8] 4.60 0.300 1.4 0.200
# 3: versicolor (4,6] 4.05 0.525 1.3 0.275
# 4: virginica (6,8] 5.60 0.700 2.1 0.500
# 5: virginica (4,6] 5.00 0.200 1.9 0.200