Policz liczbę wystąpień dla każdej unikalnej wartości

140

Powiedzmy, że mam:

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

Teraz chcę policzyć, ile razy pojawia się każda unikalna wartość. unique(v) zwraca, jakie są unikalne wartości, ale nie ile ich jest.

> unique(v)
[1] 1 2

Chcę czegoś, co mi daje

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

ale jako bardziej ogólna linijka :) Coś bliskiego (ale nie całkiem) takiego:

#<doesn't work right> length(v[v==unique(v)])
gakera
źródło

Odpowiedzi:

179

Może szukasz stołu?

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
Pościg
źródło
7
Ach, tak, mogę tego użyć, z pewną drobną modyfikacją: t (as.data.frame (tabela (v)) [, 2]) jest dokładnie tym, czego potrzebuję, dziękuję
gakera
1
Robiłem to niezręcznie z hist. tablewydaje się nieco wolniejszy niż hist. Zastanawiam się dlaczego. Czy ktoś może potwierdzić?
Rozmyślny
2
Chase, jakaś szansa na zamówienie według częstotliwości? Mam dokładnie ten sam problem, ale moja tabela ma około 20000 wpisów i chciałbym wiedzieć, jak często występują najczęstsze wpisy.
Torvon
5
@Torvon - jasne, po prostu użyj order()na wynikach. tj.x <- as.data.frame(table(dummyData)); x[order(x$Freq, decreasing = TRUE), ]
Chase
Ta metoda nie jest dobra, jest odpowiednia tylko dla bardzo niewielu danych z dużą ilością powtórzeń, nie będzie pasować do wielu ciągłych danych z kilkoma zduplikowanymi rekordami.
Deep North
26

Jeśli masz wiele czynników (= wielowymiarowa ramka danych), możesz użyć dplyrpakietu, aby policzyć unikalne wartości w każdej kombinacji czynników:

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

Używa operatora potoku %>%do łączenia wywołań metod w ramce danych data.

antoine
źródło
21

Jest to podejście jednowierszowe przy użyciu aggregate.

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

  value count
1     1    25
2     2    75
SeaSprite
źródło
11

Funkcja table () jest dobrym rozwiązaniem, jak zasugerował Chase . Jeśli analizujesz duży zbiór danych, alternatywnym sposobem jest użycie funkcji .N w pakiecie datatable.

Upewnij się, że zainstalowałeś pakiet tabeli danych przez

install.packages("data.table")

Kod:

# 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
źródło
8

Aby uzyskać bezwymiarowy wektor całkowity, który zawiera liczbę unikatowych wartości, użyj 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"

Może to być przydatne, jeśli chcesz przekazać liczbę unikalnych wartości do innej funkcji i jest krótsze i bardziej idiomatyczne niż t(as.data.frame(table(dummyData))[,2]zamieszczone w komentarzu do odpowiedzi Chase. Dzięki Ricardo Saporta który wskazywał na to, aby mnie tutaj .

Ben
źródło
7

To działa dla mnie. Weź swój wektorv

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

Komentarz: ustaw maksymalną sumę, aby była wystarczająco duża, aby uchwycić liczbę unikalnych wartości

lub z magrittrpakietem

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

Anthony Ebert
źródło
4

Jeśli potrzebujesz mieć liczbę unikalnych wartości jako dodatkową kolumnę w ramce danych zawierającej twoje wartości (kolumnę, która może na przykład reprezentować rozmiar próbki), plyr zapewnia zgrabny sposób:

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
źródło
3
lub ddply(data_frame, .(v), count). Warto również wyraźnie powiedzieć, że potrzebujesz library("plyr")telefonu do ddplypracy.
Brian Diggs
Wydaje się dziwne w użyciu transformzamiast mutatepodczas używania plyr.
Gregor Thomas
3

Również nadanie wartości kategoriom i powołanie summary()się przyda.

> v = rep(as.factor(c(1,2, 2, 2)), 25)
> summary(v)
 1  2 
25 75 
sedeh
źródło
2

Możesz również wypróbować plik tidyverse

library(tidyverse) 
dummyData %>% 
    as.tibble() %>% 
    count(value)
# A tibble: 2 x 2
  value     n
  <dbl> <int>
1     1    25
2     2    75
rzymski
źródło
0

Jeśli chcesz działać unikatowo w data.frame (np. Train.data), a także uzyskać liczby (które mogą być używane jako waga w klasyfikatorach), możesz wykonać następujące czynności:

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
źródło
0

length (unique (df $ col)) to najprostszy sposób, jaki widzę.

Jeff Henderson
źródło
R prawdopodobnie bardzo ewoluował w ciągu ostatnich 10 lat, odkąd zadałem to pytanie.
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 Wise
źródło