Фильтр для топ-10 наивысших значений группы в наборе данных (в R)

Вопрос или проблема

Контекст: Я пытаюсь найти 10 наивысших значений подсчета в моем датафрейме при условии, что они попадают в годы 1970-1979. Мой датафрейм выглядит следующим образом:


id    lemma    year    count    
1     word1    1970    737 
2     word2    1971    767
3     word3    1972    988

и так далее…

Попытка:

#1970-е
df_n_maxcount_1970s <- df_n %>% filter(year < 1980) %>% slice_max(count, n=40)

#1980-е
df_n_maxcount_1980s <- df_n %>% filter(year == 1980:1989) %>% slice_max(count, n=40)

Это работало довольно хорошо, но есть уровень ручной работы, и в 1990 году мне пришлось увеличить n до 200, потому что было много дубликатов (т.е. одно и то же слово появлялось много раз, поэтому я не получал 10 уникальных слов при поиске топ-10 с n=10).

Вопрос: Могу ли я автоматизировать код так, чтобы в итоге получить один датафрейм, организованный следующим образом? (конечно, слово 1 в 1970 году может не равняться word1 в 1980 году, и будет 10 строк для каждого десятилетия с топ-10 слов, упорядоченных по подсчету). ИЛИ хотя бы 5 отдельных датафреймов с топ-10 значениями подсчета слов за каждое десятилетие?


decade lemma count    
1970   word1 100
1970   word2 99
1970   word3 98
1980   word1 100
1990   word1 100
2000   word1 100
2010   word1 100
```

Это можно сделать с помощью dplyr и комбинации функций group_by и агрегации. Что-то вроде этого должно сработать:

library(dplyr)

df_n <- data.frame(
  id = c(1, 2, 3),
  lemma = c("word1", "word2", "word3"),
  year = c(1970, 1971, 1972), 
  count = c(737, 767, 988)
)

df_n %>%
    # создаем столбец, который указывает на десятилетие
    mutate(decade = year - year %% 10) %>%
    group_by(decade, lemma) %>%
    # складываем значения подсчета для дублированных слов в рамках указанных групп
    summarise(count = sum(count)) %>%
    group_by(decade) %>%
    # выбираем топ-10 записей на основе подсчета в рамках указанных групп
    top_n(10, count)

Ответ или решение

Конечно, я помогу вам решить данную задачу с использованием пакета dplyr в R. Для того чтобы получить топ-10 значений по каждой декаде, мы будем следовать следующим шагам: сначала создадим новую колонку, которая будет определять декаду, затем сгруппируем данные по декадам и словам (lemma), проанализируем количество (count) для каждого слова, и, наконец, выберем топ-10 слов по количеству для каждой декады.

Вот пример кода, который решает вашу задачу:

library(dplyr)

# Пример вашего датафрейма
df_n <- data.frame(
  id = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), 
  lemma = c("word1", "word2", "word3", "word1", "word2", "word3", "word1", "word4", "word2", "word5", "word3", "word2", "word1", "word6"),
  year = c(1970, 1970, 1971, 1971, 1972, 1972, 1980, 1980, 1990, 1991, 1990, 1991, 2000, 2001),
  count = c(737, 767, 988, 344, 600, 756, 990, 200, 300, 1250, 400, 500, 700, 800)
)

# Обработка данных
top_words <- df_n %>%
  # Создаем колонку, определяющую десятилетие
  mutate(decade = year - year %% 10) %>%
  # Группируем по декаде и слову
  group_by(decade, lemma) %>%
  # Суммируем значения count для одинаковых слов
  summarise(count = sum(count), .groups = 'drop') %>%
  # Группируем по декаде, чтобы выбрать топ-10 по каждому году
  arrange(decade, desc(count)) %>%
  group_by(decade) %>%
  slice_head(n = 10) %>%
  # Убираем временные группы
  ungroup()

# Вывод результата
print(top_words)

В этом коде:

  1. Мы сначала создаем новую колонку decade, основанную на годе.
  2. Затем используем group_by для группировки по декаде и слову (lemma), и суммируем значения count для каждого слова, чтобы учесть дубликаты.
  3. Далее мы сортируем данные по decade и убыванию count, затем выбираем только 10 записей с наибольшими значениями для каждой декады с помощью slice_head.
  4. Наконец, убираем временные группы с помощью ungroup().

Этот подход дает вам один датафрейм, содержащий топ-10 слов по количеству для каждой декады, что позволяет избежать дополнительных манипуляций и ручных операций.

Оцените материал
Добавить комментарий

Капча загружается...