Compter le nombre de lignes à l'intérieur de chaque groupe
J'ai un dataframe et je voudrais compter le nombre de lignes à l'intérieur de chaque groupe. J'ai regulièrement utiliser le aggregate
fonction de la somme des données comme suit:
df2 <- aggregate(x ~ Year + Month, data = df1, sum)
Maintenant, je voudrais compter les observations, mais n'arrive pas à trouver le bon argument pour FUN
. Intuitivement, je pensais que ce serait comme suit:
df2 <- aggregate(x ~ Year + Month, data = df1, count)
Mais, pas de chance.
Des idées?
D'un jouet de données:
set.seed(2)
df1 <- data.frame(x = 1:20,
Year = sample(2012:2014, 20, replace = TRUE),
Month = sample(month.abb[1:3], 20, replace = TRUE))
nrow
,NROW
,length
...- Je lis ce qu'on leur demande pour une façon amusante de compter les choses (contrairement aux nombreux n'était pas marrante façons, je suppose).
nrow
n'a pas fonctionné pour moi, maisNROW
etlength
a bien fonctionné. +1
Vous devez vous connecter pour publier un commentaire.
Les meilleures pratiques actuelles (tidyverse) est:
cbind
les résultats deaggregate(Sepal.Length ~ Species, iris, mean)
etaggregate(Sepal.Length ~ Species, iris, length)
df %>% group_by(group, variable) %>% mutate(count = n())
Suivant @Joshua suggestion, voici une façon de compter le nombre d'observations dans votre
df
dataframe oùYear
= 2007 etMonth
= Nov (en supposant qu'ils sont des colonnes):et avec
aggregate
, à la suite de @GregSnow:dplyr
paquet fait aveccount
/tally
commandes, ou lan()
fonction:D'abord, quelques données:
Maintenant le comte:
On peut aussi utiliser un peu plus de la version avec la tuyauterie et de la
n()
fonction:ou la
tally
fonction:Une vieille question sans
data.table
solution. Alors voilà...À l'aide de
.N
.()
au lieu delist()
etsetDT()
convertir des données.trame de données.table. Donc, en une seule étapesetDT(df)[, .N, by = .(year, month)]
.L'option simple à utiliser avec
aggregate
est lelength
fonction qui va vous donner la longueur du vecteur dans le sous-ensemble. Parfois un peu plus robuste consiste à utiliserfunction(x) sum( !is.na(x) )
.Une alternative à la
aggregate()
fonction dans ce cas seraittable()
avecas.data.frame()
, qui indique également les combinaisons de l'Année et le Mois sont associés à zéro occurrencesEt sans le zéro-produisent des combinaisons
Créer une nouvelle variable
Count
avec une valeur de 1 pour chaque ligne:Ensuite regrouper dataframe, résumant par la
Count
colonne:aggregate
, il n'est pas nécessaire de renommer chaque variable dansby=
commelist(year=df1$year)
etc. Undata.frame
est unlist
déjà siaggregate(df1[c("Count")], by=df1[c("Year", "Month")], FUN=sum, na.rm=TRUE)
fonctionne.Si vous souhaitez inclure 0 compte pour le mois en années, qui sont manquantes dans les données, vous pouvez utiliser un peu de
table
de la magie.Par exemple, le jeu de données.cadre dans la question, df1, ne contient pas d'observations de janvier 2014.
La base de R
aggregate
fonction ne renvoie pas à une observation de janvier 2014.Si vous souhaitez une observation de ce mois-année, avec 0 comme le comte, puis le code ci-dessus sera de retour de données.cadre avec des comptes pour tous les mois de l'année combinaisons:
Pour mon agrégations j'ai l'habitude de envie de voir la moyenne et "quelle est la taille de ce groupe" (un.k.un. la longueur).
Donc, c'est ma pratique extrait de code pour ces occasions;
Un sql la solution à l'aide de
sqldf
package:Considérant @Ben réponse, R renvoie une erreur si
df1
ne contient pas dex
colonne. Mais il peut être résolu avec élégance avecpaste
:De même, il peut être généralisée si plus de deux variables sont utilisées dans le groupement:
Vous pouvez utiliser
by
fonctions commeby(df1$Year, df1$Month, count)
qui va produire une liste d'agrégation.La sortie ressemblera,
Il ya beaucoup de merveilleuses réponses ici déjà, mais je voulais la jeter dans 1 option de plus pour ceux qui veulent ajouter une nouvelle colonne dans le jeu de données d'origine qui contient le nombre de fois que la ligne est répétée.
La même chose peut être accompli par la combinaison d'aucune des réponses ci-dessus, avec la
merge()
fonction.