Анализ активности пользователей Digida: различия между версиями

Материал из Поле цифровой дидактики
Строка 237: Строка 237:
[[Файл:Топ-10.png|800px]]
[[Файл:Топ-10.png|800px]]
[[Файл:Активность по дням недели.png|800px]]
[[Файл:Активность по дням недели.png|800px]]
=== Графики ===
=== Объединённый график ===
Объединённый график
[[Файл:Объединённый график.png| 800px]]
[[Файл:Объединённый график.png| 800px]]


На графике указаны динамика активности пользователей по месяцам, активность по дням недели, активность по часам суток.
На графике указаны динамика активности пользователей по месяцам, активность по дням недели, активность по часам суток.
----
----
[[Категория:BigDataWorks]]
[[Категория:BigDataWorks]]

Версия от 14:51, 13 апреля 2026

Исходные данные
Все события площадки до 06.04.2026 года - https://raw.githubusercontent.com/patarakin/stat-data/dc76a94554ecd09228ad4e21e95a94e9c422b1b8/datasets/csv/wiki_df_events_digid.csv
Совместные действия участников - https://raw.githubusercontent.com/patarakin/stat-data/dc76a94554ecd09228ad4e21e95a94e9c422b1b8/datasets/csv/wiki_df_team_digid.csv


График активности 2022 - 2026

Код для получения данных и графиков

# Загрузка необходимых пакетов
library(httr)
library(jsonlite)
library(dplyr)
library(lubridate)
library(tidyr)
library(ggplot2)
library(patchwork)

# Корректный URL API
api_url <- "https://digida.mgpu.ru/api.php"

# Безопасное определение функции (если ещё не существует)
if (!exists("get_mw_data")) {
  get_mw_data <- function(action, params) {
    query_params <- c(action = action, format = "json", params)
    response <- GET(api_url, query = query_params)
    
    # Дополнительная проверка типа ответа
    if (http_type(response) != "application/json") {
      warning("Ответ не в формате JSON")
    }
    
    stop_for_status(response)
    fromJSON(content(response, "text"))
  }
}

# Загрузка данных с обработкой ошибок
data_loaded <- FALSE
tryCatch({
  recent_edits <- get_mw_data("query", list(
    list = "recentchanges",
    rcprop = "user|timestamp|title|comment|type",
    rclimit = "500",
    rcshow = "!bot",
    rcend = format(Sys.Date() - 365, "%Y%m%d%H%M%S")
  ))
  
  users_list <- get_mw_data("query", list(
    list = "allusers",
    aulimit = "500"
  ))
  
  print("Данные успешно загружены!")
  data_loaded <- TRUE
}, error = function(e) {
  print(paste("Ошибка при загрузке данных:", e$message))
})

# Если данные не загружены, прерываем выполнение
if (!data_loaded) {
  stop("Не удалось загрузить данные. Прекращение выполнения.")
}

# Проверка прав на запись в текущей директории
can_write <- file.access(getwd(), mode = 2) == 0
if (!can_write) {
  stop("Нет прав на запись в текущую рабочую директорию. Выберите другую папку.")
}

# Очистка данных
clean_data <- recent_edits$query$recentchanges %>%
  as_tibble() %>%
  mutate(
    timestamp = ymd_hms(timestamp),
    date = as.Date(timestamp),
    day_of_week = wday(timestamp, label = TRUE, abbr = FALSE),
    hour_of_day = hour(timestamp),
    month = month(timestamp, label = TRUE),
    is_edit = type == "edit"
  ) %>%
  filter(date >= Sys.Date() - 365) %>%
  select(user, timestamp, date, day_of_week, hour_of_day, month, title, is_edit)

# Проверка на пустые данные
if (nrow(clean_data) == 0) {
  stop("Очищенные данные пусты. Проверьте параметры запроса к API.")
}

print(paste("Обработано записей:", nrow(clean_data)))

# Агрегация и анализ
user_summary <- clean_data %>%
  group_by(user) %>%
  summarise(
    total_actions = n(),
    edits_count = sum(is_edit),
    unique_pages = n_distinct(title),
    first_action = min(timestamp),
    last_action = max(timestamp)
  ) %>%
  arrange(desc(total_actions))

new_users <- clean_data %>%
  group_by(month) %>%
  summarise(new_users = n_distinct(user))

weekly_activity <- clean_data %>%
  group_by(day_of_week) %>%
  summarise(actions = n())

hourly_activity <- clean_data %>%
  group_by(hour_of_day) %>%
  summarise(actions = n())

top_10_users <- user_summary %>% head(10)
monthly_activity <- clean_data %>%
  group_by(month) %>%
  summarise(total_actions = n(), unique_users = n_distinct(user))

# Построение графиков
p1 <- ggplot(monthly_activity, aes(x = month, y = total_actions)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(title = "Динамика активности пользователей по месяцам",
       x = "Месяц", y = "Количество действий") +
  theme_minimal()

p2 <- ggplot(weekly_activity, aes(x = day_of_week, y = actions)) +
  geom_bar(stat = "identity", fill = "darkgreen") +
  labs(title = "Активность по дням недели",
       x = "День недели", y = "Количество действий") +
  theme_minimal()

p3 <- ggplot(hourly_activity, aes(x = hour_of_day, y = actions)) +
  geom_line(color = "red", size = 1) +
  labs(title = "Активность по часам суток",
       x = "Час дня", y = "Количество действий") +
  scale_x_continuous(breaks = 0:23) +
  theme_minimal()

combined_plot <- (p1 | p2) / p3

# Создаём папку для сохранения графиков
output_dir <- "saved_plots"
if (!dir.exists(output_dir)) {
  dir.create(output_dir)
  print(paste("Создана папка для графиков:", output_dir))
}

# Функция для безопасного сохранения графиков
safe_save_plot <- function(plot_obj, filename, width, height, dpi = 300) {
  if (!inherits(plot_obj, "ggplot")) {
    print(paste("Предупреждение: объект не является графиком ggplot — пропуск сохранения", filename))
    return(FALSE)
  }
  
  full_path <- file.path(output_dir, filename)
  
  tryCatch({
    ggsave(
      filename = full_path,
      plot = plot_obj,
      width = width,
      height = height,
      dpi = dpi,
      device = "png"
    )
    print(paste("График сохранён:", normalizePath(full_path)))
    TRUE
  }, error = function(e) {
    print(paste("Ошибка сохранения", filename, ":", e$message))
    FALSE
  })
}

# Сохранение всех графиков
print("Начинаем сохранение графиков...")

# Объединённый график
safe_save_plot(
  combined_plot,
  "activity_analysis_2023_2024.png",
  width = 12,
  height = 8
)

# График по месяцам
safe_save_plot(
  p1,
  "monthly_activity_2023_2024.png",
  width = 8,
  height = 6
)

# График по дням недели
safe_save_plot(
  p2,
  "weekly_activity_2023_2024.png",
  width = 8,
  height = 6
)

# График по часам
safe_save_plot(
  p3,
  "hourly_activity_2023_2024.png",
  width = 8,
  height = 6
)

# Финальная проверка — список сохранённых файлов
print("\n---")
print("Проверка сохранённых файлов:")
saved_files <- list.files(output_dir, pattern = ".png", full.names = TRUE)
if (length(saved_files) > 0) {
  print("Успешно сохранены файлы:")
  print(saved_files)
} else {
  print("Файлы не найдены в папке", output_dir)
}

print("Анализ завершён!")

Результаты выполнения кода

После успешного выполнения скрипт: 1. Загружает данные о действиях пользователей из API за последний год. 2. Очищает и структурирует данные. 3. Анализирует активность по месяцам, дням недели и часам суток. 4. Определяет топ‑10 активных пользователей. 5. Строит и сохраняет 4 графика в папке saved_plots. 6. Выводит сводную информацию о результатах.

Объединённый график

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