Compter le nombre d'occurrences pour chaque valeur unique

140

Disons que j'ai:

v = rep(c(1,2, 2, 2), 25)

Maintenant, je veux compter le nombre de fois où chaque valeur unique apparaît. unique(v) renvoie ce que sont les valeurs uniques, mais pas leur nombre.

> unique(v)
[1] 1 2

Je veux quelque chose qui me donne

length(v[v==1])
[1] 25
length(v[v==2])
[1] 75

mais comme un one-liner plus général :) Quelque chose de proche (mais pas tout à fait) comme ça:

#<doesn't work right> length(v[v==unique(v)])
gakera
la source

Réponses:

179

Peut-être que la table est ce que vous recherchez?

dummyData = rep(c(1,2, 2, 2), 25)

table(dummyData)
# dummyData
#  1  2 
# 25 75

## or another presentation of the same data
as.data.frame(table(dummyData))
#    dummyData Freq
#  1         1   25
#  2         2   75
Chasse
la source
7
Ah, oui, je peux utiliser ceci, avec quelques légères modifications: t (as.data.frame (table (v)) [, 2]) est exactement ce dont j'ai besoin, merci
gakera
1
J'avais l'habitude de faire ça maladroitement avec hist. tablesemble un peu plus lent que hist. Je me demande pourquoi. Quelqu'un peut-il confirmer?
Museful
2
Chase, une chance de commander par fréquence? J'ai exactement le même problème, mais ma table contient environ 20000 entrées et j'aimerais savoir à quelle fréquence les entrées les plus courantes sont.
Torvon
5
@Torvon - bien sûr, utilisez simplement order()les résultats. iex <- as.data.frame(table(dummyData)); x[order(x$Freq, decreasing = TRUE), ]
Chase
Cette méthode n'est pas bonne, elle ne convient que pour très peu de données avec beaucoup de répétitions, elle ne s'adaptera pas à beaucoup de données continues avec peu d'enregistrements dupliqués.
Deep North
26

Si vous avez plusieurs facteurs (= un bloc de données multidimensionnel), vous pouvez utiliser le dplyrpackage pour compter des valeurs uniques dans chaque combinaison de facteurs:

library("dplyr")
data %>% group_by(factor1, factor2) %>% summarize(count=n())

Il utilise l'opérateur de canal %>%pour enchaîner les appels de méthode sur le bloc de données data.

Antoine
la source
21

C'est une approche en une seule ligne en utilisant aggregate.

> aggregate(data.frame(count = v), list(value = v), length)

  value count
1     1    25
2     2    75
SeaSprite
la source
11

La fonction table () est une bonne solution, comme l'a suggéré Chase . Si vous analysez un ensemble de données volumineux, une autre méthode consiste à utiliser la fonction .N dans un package datatable.

Assurez-vous d'avoir installé le package de table de données en

install.packages("data.table")

Code:

# Import the data.table package
library(data.table)

# Generate a data table object, which draws a number 10^7 times  
# from 1 to 10 with replacement
DT<-data.table(x=sample(1:10,1E7,TRUE))

# Count Frequency of each factor level
DT[,.N,by=x]
C. Zeng
la source
8

Pour obtenir un vecteur entier non dimensionné contenant le nombre de valeurs uniques, utilisez c().

dummyData = rep(c(1, 2, 2, 2), 25) # Chase's reproducible data
c(table(dummyData)) # get un-dimensioned integer vector
 1  2 
25 75

str(c(table(dummyData)) ) # confirm structure
 Named int [1:2] 25 75
 - attr(*, "names")= chr [1:2] "1" "2"

Cela peut être utile si vous devez alimenter les décomptes de valeurs uniques dans une autre fonction, et est plus court et plus idiomatique que celui t(as.data.frame(table(dummyData))[,2]publié dans un commentaire à la réponse de Chase. Merci à Ricardo Saporta qui me l'a fait remarquer ici .

Ben
la source
7

Cela fonctionne pour moi. Prenez votre vecteurv

length(summary(as.factor(v),maxsum=50000))

Commentaire: définissez maxsum pour être suffisamment grand pour capturer le nombre de valeurs uniques

ou avec le magrittrpackage

v %>% as.factor %>% summary(maxsum=50000) %>% length

Anthony Ebert
la source
4

Si vous avez besoin d'avoir le nombre de valeurs uniques en tant que colonne supplémentaire dans le bloc de données contenant vos valeurs (une colonne qui peut représenter la taille de l'échantillon par exemple), plyr fournit un moyen simple:

data_frame <- data.frame(v = rep(c(1,2, 2, 2), 25))

library("plyr")
data_frame <- ddply(data_frame, .(v), transform, n = length(v))
Lionel Henry
la source
3
ou ddply(data_frame, .(v), count). Cela vaut également la peine library("plyr")de préciser que vous avez besoin d'un appel pour ddplytravailler.
Brian Diggs
Cela semble étrange à utiliser transformau lieu de mutatelors de l'utilisation plyr.
Gregor Thomas
3

Rendre les valeurs catégoriques et appelantes summary()fonctionnerait également.

> v = rep(as.factor(c(1,2, 2, 2)), 25)
> summary(v)
 1  2 
25 75 
sedeh
la source
2

Vous pouvez également essayer un tidyverse

library(tidyverse) 
dummyData %>% 
    as.tibble() %>% 
    count(value)
# A tibble: 2 x 2
  value     n
  <dbl> <int>
1     1    25
2     2    75
romain
la source
0

Si vous souhaitez exécuter unique sur un data.frame (par exemple, train.data), et également obtenir les décomptes (qui peuvent être utilisés comme poids dans les classificateurs), vous pouvez faire ce qui suit:

unique.count = function(train.data, all.numeric=FALSE) {                                                                                                                                                                                                 
  # first convert each row in the data.frame to a string                                                                                                                                                                              
  train.data.str = apply(train.data, 1, function(x) paste(x, collapse=','))                                                                                                                                                           
  # use table to index and count the strings                                                                                                                                                                                          
  train.data.str.t = table(train.data.str)                                                                                                                                                                                            
  # get the unique data string from the row.names                                                                                                                                                                                     
  train.data.str.uniq = row.names(train.data.str.t)                                                                                                                                                                                   
  weight = as.numeric(train.data.str.t)                                                                                                                                                                                               
  # convert the unique data string to data.frame
  if (all.numeric) {
    train.data.uniq = as.data.frame(t(apply(cbind(train.data.str.uniq), 1, 
      function(x) as.numeric(unlist(strsplit(x, split=","))))))                                                                                                    
  } else {
    train.data.uniq = as.data.frame(t(apply(cbind(train.data.str.uniq), 1, 
      function(x) unlist(strsplit(x, split=",")))))                                                                                                    
  }
  names(train.data.uniq) = names(train.data)                                                                                                                                                                                          
  list(data=train.data.uniq, weight=weight)                                                                                                                                                                                           
}  
utilisateur2771312
la source
0

length (unique (df $ col)) est le moyen le plus simple que je puisse voir.

Jeff Henderson
la source
R a probablement beaucoup évolué au cours des 10 dernières années, depuis que j'ai posé cette question.
gakera le
-2
count_unique_words <-function(wlist) {
ucountlist = list()
unamelist = c()
for (i in wlist)
{
if (is.element(i, unamelist))
    ucountlist[[i]] <- ucountlist[[i]] +1
else
    {
    listlen <- length(ucountlist)
    ucountlist[[i]] <- 1
    unamelist <- c(unamelist, i)
    }
}
ucountlist
}

expt_counts <- count_unique_words(population)
for(i in names(expt_counts))
    cat(i, expt_counts[[i]], "\n")
Michael Wise
la source