Cuenta el número de ocurrencias para cada valor único


140

Digamos que tengo:

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

Ahora, quiero contar la cantidad de veces que aparece cada valor único. unique(v) devuelve cuáles son los valores únicos, pero no cuántos son.

> unique(v)
[1] 1 2

Quiero algo que me de

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

pero como una frase más general :) Algo cercano (pero no del todo) como este:

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

Respuestas:


179

Tal vez la mesa es lo que buscas?

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

77
Ah, sí, puedo usar esto, con alguna ligera modificación: t (as.data.frame (table (v)) [, 2]) es exactamente lo que necesito, gracias
gakera

1
Solía ​​hacer esto con torpeza hist. tableparece bastante más lento que hist. Me pregunto porque. ¿Alguien puede confirmar?
Museful

2
Chase, ¿hay alguna posibilidad de ordenar por frecuencia? Tengo exactamente el mismo problema, pero mi tabla tiene aproximadamente 20000 entradas y me gustaría saber con qué frecuencia son las entradas más comunes.
Torvon

55
@Torvon: claro, solo úsalo order()en los resultados. es decirx <- as.data.frame(table(dummyData)); x[order(x$Freq, decreasing = TRUE), ]
Chase

Este método no es bueno, solo es adecuado para muy pocos datos con muchos datos repetidos, no se ajustará a muchos datos continuos con pocos registros duplicados.
Deep North

26

Si tiene múltiples factores (= un marco de datos multidimensional), puede usar el dplyrpaquete para contar valores únicos en cada combinación de factores:

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

Utiliza el operador de tubería %>%para encadenar llamadas de método en el marco de datos data.


21

Es un enfoque de una línea mediante el uso aggregate.

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

  value count
1     1    25
2     2    75

11

La función table () es una buena opción, como sugirió Chase . Si está analizando un conjunto de datos grande, una forma alternativa es usar la función .N en el paquete de tabla de datos.

Asegúrese de haber instalado el paquete de la tabla de datos

install.packages("data.table")

Código:

# 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]

8

Para obtener un vector entero no acotado que contiene el recuento de valores únicos, use 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"

Esto puede ser útil si necesita alimentar los recuentos de valores únicos en otra función, y es más corto y más idiomático que el t(as.data.frame(table(dummyData))[,2]publicado en un comentario a la respuesta de Chase. Gracias a Ricardo Saporta que me lo señaló aquí .


7

Esto funciona para mi. Toma tu vectorv

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

Comentario: establezca maxsum para que sea lo suficientemente grande como para capturar la cantidad de valores únicos

o con el magrittrpaquete

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


4

Si necesita tener el número de valores únicos como una columna adicional en el marco de datos que contiene sus valores (una columna que puede representar el tamaño de la muestra, por ejemplo), plyr proporciona una forma ordenada:

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

library("plyr")
data_frame <- ddply(data_frame, .(v), transform, n = length(v))

3
o ddply(data_frame, .(v), count). También vale la pena hacer explícito que necesita una library("plyr")llamada para que ddplyfuncione.
Brian Diggs

Parece extraño usarlo en transformlugar de mutateusarlo plyr.
Gregor Thomas

3

También hacer que los valores sean categóricos y llamar summary()funcionaría.

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

2

Puedes probar también un tidyverse

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

0

Si desea ejecutar un único en un data.frame (por ejemplo, train.data), y también obtener los recuentos (que se pueden usar como el peso en los clasificadores), puede hacer lo siguiente:

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

length (unique (df $ col)) es la forma más simple que puedo ver.


R probablemente ha evolucionado mucho en los últimos 10 años, desde que hice esta pregunta.
gakera

-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")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.