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)])
gakera
fuente

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
Persecución
fuente
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.

antoine
fuente
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
SeaSprite
fuente
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]
C. Zeng
fuente
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í .

Ben
fuente
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

Anthony Ebert
fuente
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))
Lionel Henry
fuente
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 
sedeh
fuente
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
romano
fuente
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)                                                                                                                                                                                           
}  
usuario2771312
fuente
0

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

Jeff Henderson
fuente
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")
Michael sabio
fuente