Получите сводную частоту в столбце, содержащем список значений в R

#r #datatable #summary

Вопрос:

У меня есть фрейм данных, такой как :

                                ANIMALS     query
3                                          A
4                         [CAT], [DOG]     B
5                                          C
6                                [CAT]     D
7                                          E
8                [CAT], [SHARK], [DOG]     F
 

и я хотел бы получить краткое описание соотношения элементов списка чисел между ЖИВОТНЫМИ

Ожидаемое резюме :

 ANIMALS  Freq
CAT      0.50
DOG      0.33
SHARK    0.17
 

Вот кадр данных в формате dput, если это может помочь:

 structure(list(ANIMALS = list(character(0), 
    c("[CAT]", "[DOG]"), character(0), "[CAT]", 
    character(0), c("[CAT]", "[SHARK]", "[DOG]"
    )), query = c("A", 
"B", "C", 
"D", "E", 
"F")), row.names = 3:8, class = "data.frame")
 

До сих пор я пытался использовать традиционное table(tab$ANIMALS) , но это не работает.

Ответ №1:

Вот решение dplyr и stringr:

 library(dplyr)
library(stringr)

unlist(dat$ANIMALS) %>%
 str_extract(., "[A-Z] " ) %>%
 data.frame(ANIMALS= .) %>%
 group_by(ANIMALS) %>%
 summarise(total = n() ) %>%
 mutate(Freq = total/sum(total))
 

Ответ №2:

Более низкое решение

 animal <- unlist(Filter(length, mydata$ANIMALS))
as.data.frame(table(animal)/length(animal))
#    animal      Freq
# 1   [CAT] 0.5000000
# 2   [DOG] 0.3333333
# 3 [SHARK] 0.1666667
 

Комментарии:

1. Хорошенькая. Отличное решение!

Ответ №3:

Другой подход:

 library(dplyr)
library(tidyr)
library(stringr)

df %>% select(ANIMALS) %>% unnest(ANIMALS) %>% 
  mutate(ANIMALS = str_remove_all(ANIMALS, '\[|\]'), l = n()) %>% 
    group_by(ANIMALS) %>% summarise(Freq = n()/l) %>% distinct()
`summarise()` has grouped output by 'ANIMALS'. You can override using the `.groups` argument.
# A tibble: 3 x 2
# Groups:   ANIMALS [3]
  ANIMALS  Freq
  <chr>   <dbl>
1 CAT     0.5  
2 DOG     0.333
3 SHARK   0.167
 

Ответ №4:

Мы также можем сделать

 library(dplyr)
library(tidyr)
library(stringr)
df1 %>% 
   filter(lengths(ANIMALS) > 0) %>% 
   unnest(ANIMALS) %>% 
   count(ANIMALS = str_remove_all(ANIMALS, "\[|\]"), name = 'Freq') %>% 
   mutate(Freq = Freq/sum(Freq))
 

-выход

 # A tibble: 3 × 2
  ANIMALS  Freq
  <chr>   <dbl>
1 CAT     0.5  
2 DOG     0.333
3 SHARK   0.167
 

Или в base R

 proportions(table(unlist(df1$ANIMALS)))

    [CAT]     [DOG]   [SHARK] 
0.5000000 0.3333333 0.1666667