Подсчитать количество вхождений для каждого уникального значения

145

Допустим, у меня есть:

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

Теперь я хочу подсчитать, сколько раз появляется каждое уникальное значение. unique(v) возвращает уникальные значения, но не их количество.

> unique(v)
[1] 1 2

Я хочу то, что дает мне

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

но как более общий однострочный :) Что-то близкое (но не совсем) вроде этого:

#<doesn't work right> length(v[v==unique(v)])
гакера
источник

Ответы:

183

Может, стол - это то, что вам нужно?

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
гнаться
источник
7
Ах, да, я могу использовать это, с некоторыми небольшими изменениями: t (as.data.frame (table (v)) [, 2]) - именно то, что мне нужно, спасибо
gakera
1
Раньше я делал это неловко с hist. tableкажется немного медленнее, чем hist. Интересно, почему. Кто-нибудь может подтвердить?
Museful
2
Чейз, есть ли шанс заказать по частоте? У меня точно такая же проблема, но в моей таблице около 20000 записей, и я хотел бы знать, насколько часто встречаются наиболее распространенные записи.
Торвон 01
5
@Torvon - конечно, просто пользуйся order()результатами. iex <- as.data.frame(table(dummyData)); x[order(x$Freq, decreasing = TRUE), ]
Chase
Этот метод не годится, он подходит только для очень небольшого количества данных с большим количеством повторений, он не подходит для большого количества непрерывных данных с несколькими повторяющимися записями.
Deep North
29

Если у вас есть несколько факторов (= многомерный фрейм данных), вы можете использовать dplyrпакет для подсчета уникальных значений в каждой комбинации факторов:

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

Он использует оператор конвейера %>%для цепочки вызовов методов во фрейме данных data.

Антуан
источник
Как вариант, и немного короче:data %>% count(factor1, factor2)
Дэвид
21

Это однострочный подход с использованием aggregate.

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

  value count
1     1    25
2     2    75
SeaSprite
источник
11

Как предложил Чейз, можно использовать функцию table () . Если вы анализируете большой набор данных, альтернативным способом является использование функции .N в пакете данных.

Убедитесь, что вы установили пакет таблиц данных,

install.packages("data.table")

Код:

# 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

Чтобы получить безразмерный целочисленный вектор, содержащий количество уникальных значений, используйте 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"

Это может быть полезно, если вам нужно передать количество уникальных значений в другую функцию, и оно короче и идиоматичнее, чем t(as.data.frame(table(dummyData))[,2]опубликованное в комментарии к ответу Чейза. Спасибо Рикардо Сапорте, который указал мне на это здесь .

Бен
источник
7

У меня это работает. Возьми свой векторv

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

Комментарий: установите maxsum достаточно большим, чтобы захватить количество уникальных значений

или с magrittrпакетом

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

Энтони Эберт
источник
4

Если вам нужно указать количество уникальных значений в качестве дополнительного столбца во фрейме данных, содержащем ваши значения (например, столбец, который может представлять размер выборки), plyr предоставляет удобный способ:

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
или ddply(data_frame, .(v), count). Также стоит четко указать, что вам нужен library("plyr")звонок, чтобы заставить ddplyработать.
Брайан Диггс,
Кажется странным использовать transformвместо того, чтобы mutateиспользовать plyr.
Грегор Томас
3

Также summary()сработает категоричность ценностей и вызов .

> v = rep(as.factor(c(1,2, 2, 2)), 25)
> summary(v)
 1  2 
25 75 
Седех
источник
3

Вы также можете попробовать tidyverse

library(tidyverse) 
dummyData %>% 
    as.tibble() %>% 
    count(value)
# A tibble: 2 x 2
  value     n
  <dbl> <int>
1     1    25
2     2    75
Римский
источник
0

Если вы хотите запустить unique в data.frame (например, train.data), а также получить подсчеты (которые можно использовать в качестве веса в классификаторах), вы можете сделать следующее:

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
источник
0

Я знаю , что есть много других ответов, но здесь это еще один способ сделать это , используя sortи rleфункцию. Функция rleрасшифровывается как Run Length Encoding . Его можно использовать для подсчета серий чисел (см. Документацию по R man rle), но также можно применить и здесь.

test.data = rep(c(1, 2, 2, 2), 25)
rle(sort(test.data))
## Run Length Encoding
##   lengths: int [1:2] 25 75
##   values : num [1:2] 1 2

Если вы зафиксируете результат, вы можете получить доступ к длинам и значениям следующим образом:

## rle returns a list with two items.
result.counts <- rle(sort(test.data))
result.counts$lengths
## [1] 25 75
result.counts$values
## [1] 1 2
стивеб
источник
0

length(unique(df$col)) это самый простой способ увидеть.

Джефф Хендерсон
источник
R, вероятно, сильно изменился за последние 10 лет с тех пор, как я задал этот вопрос.
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")
Майкл Уайз
источник