Как сгруппировать факторы с низкой частотой в «другой» фактор в R

# Generate counts table
library(plyr)
example <- data.frame(count(diamonds,c('color', 'cut')))
example[1:3,]

# Excerpt of table
       color  cut   freq
1      D      Fair  163
2      D      Good  662
3      D Very Good 1513

Вы можете легко отфильтровать таблицу по частоте> 1000 с помощью: example[example$freq > 1000,]. Я хотел бы создать таблицу, подобную этой, за исключением того, что все значения меньше значения, например. 1000 включаются в строку (Other) аналогично тому, что происходит, когда у вас слишком много факторов и вызывается summary(example, maxsum=3).

     color         cut          freq     
 D      : 5   Fair   : 7   Min.   : 119  
 E      : 5   Good   : 7   1st Qu.: 592  
 (Other):25   (Other):21   Median :1204  
                           Mean   :1541  
                           3rd Qu.:2334  
                           Max.   :4884 

Пример идеального вывода:

В идеале я хочу преобразовать это example[example$color=='J',]:

 color   cut freq
 J      Fair  119
 J      Good  307
 J Very Good  678
 J   Premium  808
 J     Ideal  896

и произвести это:

 color       cut freq
     J Very Good  678
     J   Premium  808
     J     Ideal  896
     J   (Other)  426 

Бонус: если такая фильтрация возможна с помощью ggplot для создания графика, как показано ниже, но с этой фильтрацией, это тоже было бы здорово.

ggplot(example, aes(x=color, y=freq)) + geom_bar(aes(fill=cut), stat = "identity")

введите здесь описание изображения


person amblina    schedule 06.04.2016    source источник
comment
Взгляните на этот похожий вопрос: stackoverflow.com/questions/23730067/ создание-другого-поля   -  person talat    schedule 06.04.2016
comment
Итак, каков ваш порог для Other ?   -  person mtoto    schedule 06.04.2016
comment
@mtoto Я не возражаю против числа, но я хочу, чтобы частота «вырезанных» факторов с меньшим порогом была сгруппирована (по цвету). Порог частоты ‹ 500 может быть?   -  person amblina    schedule 06.04.2016
comment
@docendodiscimus, спасибо за ссылку, посмотрю.   -  person amblina    schedule 06.04.2016
comment
@amblina это то, что вы ищете?   -  person mtoto    schedule 06.04.2016


Ответы (2)


Вот альтернатива использования dplyr для передачи правильных данных непосредственно в вызов ggplot.

library(dplyr)
example %>% mutate(cut = ifelse(freq < 500, "Other", levels(cut))) %>%
  group_by(color, cut) %>%
  summarise(freq = sum(freq)) %>%
  ggplot(aes(color, freq, fill = cut)) +
  geom_bar(stat = "identity")

введите здесь описание изображения

Обязательно отсоедините plyr, иначе вывод из вызова dplyr будет неправильным.

person mtoto    schedule 06.04.2016

Попробуй это:

library(plyr)
library(ggplot2)
example <- data.frame(count(diamonds,c('color', 'cut')))


# Compute the row id where frequency is lower than some threshold
idx <- example$freq < 1000

# Create a helper function that adds the level "Other" to a vector
add_other_level <- function(x){
  levels(x) <- c(levels(x), "Other")
  x
}

# Change the factor leves for the threshold id rows
example <- within(example, 
       {
         color <- add_other_level(color)
         color[idx] <- "Other"
         cut <- add_other_level(cut)
         cut[idx]    <- "Other"
       }
)

# Create a plot
ggplot(example, aes(x = color, y = freq, fill = cut)) + 
  geom_bar(stat = "identity")

введите здесь описание изображения

person Andrie    schedule 06.04.2016