Contar o número de ocorrências para cada valor exclusivo

140

Digamos que eu tenho:

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

Agora, quero contar o número de vezes que cada valor exclusivo aparece. unique(v) retorna quais são os valores únicos, mas não quantos são.

> unique(v)
[1] 1 2

Eu quero algo que me dê

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

mas como um one-liner mais geral :) Algo próximo (mas não muito) assim:

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

Respostas:

179

Talvez tabela é o que você está procurando?

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
correr atrás
fonte
7
Ah, sim, eu posso usar isso, com alguma pequena modificação: t (as.data.frame (tabela (v)) [, 2]) é exatamente o que eu preciso, obrigado
gakera
1
Eu costumava fazer isso sem jeito hist. tableparece um pouco mais lento que hist. Eu quero saber porque. Alguém pode confirmar?
Museful
2
Chase, alguma chance de pedir por frequência? Eu tenho exatamente o mesmo problema, mas minha tabela possui aproximadamente 20.000 entradas e eu gostaria de saber com que frequência as entradas mais comuns são.
Torvon
5
@ Torvon - claro, basta usar order()nos resultados. iex <- as.data.frame(table(dummyData)); x[order(x$Freq, decreasing = TRUE), ]
perseguição
Este método não é bom, é adequado apenas para muito poucos dados com muitas repetições, não caberá muitos dados contínuos com poucos registros duplicados.
Deep North
26

Se você tiver vários fatores (= um quadro de dados multidimensional), poderá usar o dplyrpacote para contar valores exclusivos em cada combinação de fatores:

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

Ele usa o operador %>%de canal para encadear chamadas de método no quadro de dados data.

antoine
fonte
21

É uma abordagem de uma linha usando aggregate.

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

  value count
1     1    25
2     2    75
SeaSprite
fonte
11

A função table () é um bom caminho, como sugeriu Chase . Se você estiver analisando um grande conjunto de dados, uma maneira alternativa é usar a função .N no pacote de dados.

Certifique-se de instalar o pacote da tabela de dados

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
fonte
8

Para obter um vetor inteiro não dimensionado que contenha a contagem de valores exclusivos, 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"

Isso pode ser útil se você precisar alimentar as contagens de valores exclusivos em outra função e for mais curto e mais idiomático do que o t(as.data.frame(table(dummyData))[,2]postado em um comentário à resposta de Chase. Agradeço a Ricardo Saporta, que me indicou isso aqui .

Ben
fonte
7

Isso funciona para mim. Pegue seu vetorv

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

Comentário: defina maxsum como grande o suficiente para capturar o número de valores exclusivos

ou com o magrittrpacote

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

Anthony Ebert
fonte
4

Se você precisar ter o número de valores exclusivos como uma coluna adicional no quadro de dados que contém seus valores (uma coluna que pode representar o tamanho da amostra, por exemplo), o plyr fornece uma maneira elegante:

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
fonte
3
ou ddply(data_frame, .(v), count). Também vale a pena explicitar que você precisa de uma library("plyr")chamada para fazer o ddplytrabalho.
Brian Diggs
Parece estranho de usar em transformvez de mutatequando usar plyr.
Gregor Thomas
3

Também tornar os valores categóricos e os chamados summary()funcionaria.

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

Você pode tentar também um tidyverse

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

Se você deseja executar um único em um data.frame (por exemplo, train.data) e também obter as contagens (que podem ser usadas como peso nos classificadores), faça o seguinte:

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)                                                                                                                                                                                           
}  
user2771312
fonte
0

length (unique (df $ col)) é a maneira mais simples de ver.

Jeff Henderson
fonte
O R provavelmente evoluiu muito nos últimos 10 anos, desde que fiz essa pergunta.
gakera 22/07
-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
fonte