R: Как мне сгруппировать вложенные символьные векторы c() по другому столбцу?

У меня есть строки, содержащие перечисления слов, сгруппированных по типу слова. В приведенном ниже примере для простоты используется только один тип.

ka = tibble(
  words = c('apple, orange', 'pear, apple, plum'),
  type = 'fruit'
)

Я хочу узнать количество УНИКАЛЬНЫХ слов в каждом типе.

Я решил, что разделю векторы символов,

ka = ka %>% 
  mutate(
    word_list = str_split(words, ', ')
  )

а затем свяжите столбцы для каждой группы. Конечный результат будет

c(
ka$word_list[[1]],
ka$word_list[[2]],
)

Затем я могу объединить эти векторы и получить их длину.

Я не знаю, как связать столбцы вместе, сгруппированные по отдельному столбцу. Я мог бы сделать это с уродливым циклом внутри цикла, но также должно быть решение map / apply, следуя логике:

ka %>%
  group_by(type) %>%
  summarise(
    biglist = map(word_list, ~ c(.)), # this doesn't work, obviously
    biglist_unique = map(biglist, ~ unique(.)),
    biglist_length = map(biglist_unique, ~ length(.))
  )

4 ответа

Решение

Что-то вроде этого:

library(tidyverse)
ka %>% 
  mutate(words = strsplit(as.character(words), ",")) %>% 
  unnest(words) %>% 
  mutate(words = gsub(" ","",words)) %>%
  group_by(type) %>%
  summarise(number =  n_distinct(words),
            words = paste0(unique(words), collapse =' '))

# A tibble: 1 x 3
  type  number words                 
  <chr>  <int> <chr>                 
1 fruit      4 apple orange pear plum

Вот вариант для вас. Сначала мы сворачиваем векторы, а затем намечаем то, что вы ищете. Обратите внимание, что мы должны обрезать пробелы, чтобы получить правильные уникальные слова.

library(tidyverse)

ka %>%
  group_by(type) %>%
  summarise(all_words = paste(words, collapse = ",")) %>%
  mutate(biglist = str_split(all_words, ",") %>% map(., ~str_trim(.x, "both")),
         biglist_unique = map(biglist, ~.x[unique(.x)]),
         biglist_length = map_dbl(biglist_unique, length))
#> # A tibble: 1 x 5
#>   type  all_words                       biglist   biglist_unique biglist_length
#>   <chr> <chr>                           <list>    <list>                  <dbl>
#> 1 fruit apple, orange,pear, apple, plum <chr [5]> <chr [4]>                   4

Вот как вы можете использовать separate_rows:

ka %>% 
  separate_rows(words, sep = ', ') %>% 
  group_by(type) %>% 
  summarise(word_c = n_distinct(words))

Другой вариант - использовать принципы аккуратности данных и tidyr пакет.

ka = ka %>% 
  mutate(
    word_list = str_split(words, ', ')
  )

ka %>%
  # If you need to maintain information about each row you can create an index
  # mutate(index = row_number()) %>% 
  # unnest the wordlist to get one word per row
  unnest(word_list) %>%
  # Only keep unique words per group
  group_by(type) %>%
  distinct(word_list, .keep_all = FALSE) %>% # if you need to maintain row info .keep_all = TRUE
  summarise(n_unique = n())
# A tibble: 1 x 2
# type  n_unique
#     <chr>    <int>
#   1 fruit        4  
Другие вопросы по тегам