data.table
Calculer des statistiques sommaires
Recherche…
Remarques
Un rappel: la syntaxe DT[where, select|update|do, by]
est utilisée pour travailler avec des colonnes d'un data.table.
- La partie "where" est l'argument
i
- La partie "select | update | do" est l'argument
j
Ces deux arguments sont généralement passés par position plutôt que par nom.
Compter les lignes par groupe
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
En utilisant .N
.N
dans j
stocke le nombre de lignes dans un sous-ensemble. Lors de l'exploration des données, .N
est pratique pour ...
compter les lignes dans un groupe,
DT[Species == "setosa", .N] # 50
ou compter les lignes dans tous les groupes,
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
ou trouvez des groupes qui ont un certain nombre de lignes.
DT[, .N, by=.(Species, Bin)][ N < 25 ] # Species Bin N # 1: versicolor (6,8] 20 # 2: virginica (4,6] 9
Manipulation des groupes manquants
Cependant, nous manquons de groupes avec un compte de zéro ci-dessus. S'ils sont importants, nous pouvons utiliser la table
de base:
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
Alternativement, nous pouvons rejoindre tous les groupes:
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
Une note sur .N
:
- Cet exemple utilise
.N
dansj
, où il fait référence à la taille d'un sous-ensemble. - Dans
i
, il s'agit du nombre total de lignes.
Résumés personnalisés
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
Supposons que nous voulons la sortie de la fonction de summary
pour Sepal.Length
avec le nombre d'observations:
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
Nous devons faire j
une liste de colonnes. Habituellement, certains jouent avec c
, as.list
et .
est suffisant pour trouver la bonne façon de procéder.
Affectation de statistiques récapitulatives sous forme de nouvelles colonnes
Au lieu de créer un tableau récapitulatif, nous pouvons souhaiter stocker une statistique récapitulative dans une nouvelle colonne. Nous pouvons utiliser :=
comme d'habitude. Par exemple,
DT[, is_big := .N >= 25, by=.(Species, Bin)]
Pièges
Données désordonnées
Si vous vous trouvez à vouloir analyser les noms de colonnes, comme
Prenez la moyenne de
x.Length/x.Width
oùx
prend dix valeurs différentes.
alors vous regardez probablement des données incorporées dans des noms de colonne, ce qui est une mauvaise idée. Lisez à propos des données bien rangées , puis modifiez-les au format long.
Résumés en lignes
Les blocs de données et les data.tables sont bien conçus pour les données tabulaires, où les lignes correspondent aux observations et aux colonnes aux variables. Si vous vous trouvez à vouloir résumer sur des lignes, comme
Recherchez l'écart type entre les colonnes pour chaque ligne.
alors vous devriez probablement utiliser une matrice ou un autre format de données entièrement.
La fonction récapitulative
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
summary
est pratique pour parcourir les statistiques sommaires. Outre l'utilisation directe comme summary(DT)
, il est également possible de l'appliquer par groupe de manière pratique avec la 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...]
Pour inclure des groupes à nombre de zéro, définissez drop=FALSE
dans split
.
Application d'une fonction de résumé à plusieurs variables
# example data
DT = data.table(iris)
DT[, Bin := cut(Sepal.Length, c(4,6,8))]
Pour appliquer la même fonction récapitulant à chaque colonne par groupe, nous pouvons utiliser lapply
et .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
Nous pouvons filtrer les colonnes dans .SD
avec l'argument .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
Fonctions de synthèse multiples
Actuellement, l'extension la plus simple à plusieurs fonctions est peut-être:
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
Si vous voulez que les noms soient comme Petal.Length.med
au lieu de med.Petal.Length
, changez l'ordre:
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