web-dev-qa-db-fra.com

Compter des valeurs uniques

Disons que j'ai:

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

Maintenant, je veux compter le nombre de fois que chaque valeur unique apparaît. unique(v) renvoie 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 ceci:

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

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
147
Chase

Si vous avez plusieurs facteurs (= un bloc de données multidimensionnel), vous pouvez utiliser le package dplyr 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 chaîner les appels de méthode sur le bloc de données data.

17
antoine

C'est une approche d'une ligne utilisant aggregate

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

  value count
1     1    25
2     2    75
16
SeaSprite

la fonction table () est un bon choix, comme le suggère Chase ... .. Si vous analysez un jeu de données volumineux, vous pouvez également utiliser la fonction .N dans un package datatable.

Assurez-vous d’avoir installé le paquet 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]
9
C. Zeng

Pour obtenir un vecteur entier non coté 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 le nombre de valeurs uniques dans une autre fonction. Il est plus court et plus idiomatique que la fonction t(as.data.frame(table(dummyData))[,2] affichée dans un commentaire de la réponse de Chase. Merci à Ricardo Saporta qui l’a signalé ici .

7
Ben

Si vous avez besoin du nombre de valeurs uniques en tant que colonne supplémentaire dans le bloc de données contenant vos valeurs (une colonne pouvant 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))
4
lionel

Vous pouvez aussi essayer une tidyverse

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

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

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

Si vous souhaitez exécuter une tâche unique sur un nom de données.fr (par exemple, train.data) et obtenir le nombre (qui peut être utilisé comme poids dans les classificateurs), vous pouvez procéder comme 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)                                                                                                                                                                                           
}  
0
user2771312