title: “Анализ результатов соревнований по драгонботу” subtitle: “Влияние возрастного состава на результаты команд” author: “Твое Имя” date: “27 September 2025” output: html_document: theme: flatly highlight: tango toc: true toc_float: true code_folding: show —

📊 Аналитический отчет: Соревнования по драгонботу

1. Введение

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

Исследовательские вопросы: - Как возраст спортсменов влияет на результаты команды? - Существует ли оптимальный возрастной состав для успеха в соревнованиях? - Какие факторы наиболее значимы для предсказания места команды?

2. Загрузка и подготовка данных

# Загрузка и парсинг данных
pdf_file <- "KU2025.pdf"

# Извлекаем текст из PDF
pdf_text <- pdf_text(pdf_file)
full_text <- paste(pdf_text, collapse = "\n")
text_lines <- unlist(str_split(full_text, "\n"))

cat("Загружено строк текста:", length(text_lines))
## Загружено строк текста: 947

2.1 Парсинг данных

# Функция для парсинга данных спортсменов
improved_parsing <- function(text_lines) {
  results_df <- data.frame(
    Team_Name = character(),
    Athlete_Name = character(),
    Birth_Date = character(),
    Rank = character(),
    stringsAsFactors = FALSE
  )
  
  date_lines <- which(str_detect(text_lines, "\\d{2}\\.\\d{2}\\.\\d{4}"))
  
  for (i in date_lines) {
    line <- text_lines[i]
    
    birth_date <- str_extract(line, "\\d{2}\\.\\d{2}\\.\\d{4}")
    name_part <- str_split(line, birth_date)[[1]][1]
    athlete_name <- str_trim(str_replace(name_part, "^\\d+\\s+", ""))
    athlete_name <- str_trim(str_replace(athlete_name, "^(ст|бар)\\s+", ""))
    
    after_date <- str_split(line, birth_date)[[1]][2]
    rank <- ifelse(!is.na(after_date), 
                   str_trim(str_split(after_date, "\\s+")[[1]][1]), 
                   NA)
    
    results_df <- rbind(results_df, data.frame(
      Team_Name = "Unknown",
      Athlete_Name = athlete_name,
      Birth_Date = birth_date,
      Rank = rank,
      stringsAsFactors = FALSE
    ))
  }
  
  return(results_df)
}

# Применяем парсинг
results_df <- improved_parsing(text_lines)

2.2 Очистка и подготовка данных

# Назначение команд вручную
results_df$Team_Name[1:14] <- "Волинська область"
results_df$Team_Name[15:28] <- "місто Київ"  
results_df$Team_Name[29:42] <- "Житомирська область"
results_df$Team_Name[43:56] <- "Київська область"

# Фильтрация и очистка
open_class_df <- results_df[1:56, ]
open_class_df$Athlete_Name <- str_trim(str_replace(open_class_df$Athlete_Name, "^\\d+\\.?\\s*", ""))

# Добавление рейтинга команд
open_class_df$Team_Ranking <- case_when(
  open_class_df$Team_Name == "Волинська область" ~ 1,
  open_class_df$Team_Name == "місто Київ" ~ 2,
  open_class_df$Team_Name == "Житомирська область" ~ 3,
  open_class_df$Team_Name == "Київська область" ~ 4
)

# Расчет возраста
competition_date <- as.Date("2025-04-23")
open_class_df$Birth_Date <- as.Date(open_class_df$Birth_Date, format = "%d.%m.%Y")
open_class_df$Age <- floor(as.numeric(difftime(competition_date, open_class_df$Birth_Date, units = "days")) / 365.25)

# Финальная структура данных
open_class_df <- open_class_df[, c("Team_Name", "Athlete_Name", "Birth_Date", "Age", "Team_Ranking")]

# Сохранение данных
write_csv(open_class_df, "final_athletes_data.csv")

3. Описательная статистика

3.1 Основные показатели

cat("### 📈 Основная статистика\n\n")
## ### 📈 Основная статистика
cat("**Общее количество спортсменов:**", nrow(open_class_df), "\n")
## **Общее количество спортсменов:** 56
cat("**Количество команд:**", length(unique(open_class_df$Team_Name)), "\n")
## **Количество команд:** 4
cat("**Средний возраст спортсменов:**", round(mean(open_class_df$Age), 1), "лет\n")
## **Средний возраст спортсменов:** 29.4 лет
cat("**Возрастной диапазон:** от", min(open_class_df$Age), "до", max(open_class_df$Age), "лет\n")
## **Возрастной диапазон:** от 15 до 58 лет

3.2 Статистика по командам

team_stats <- open_class_df %>%
  group_by(Team_Name, Team_Ranking) %>%
  summarise(
    Количество_спортсменов = n(),
    Средний_возраст = round(mean(Age), 1),
    Мин_возраст = min(Age),
    Макс_возраст = max(Age),
    Разброс_возрастов = Макс_возраст - Мин_возраст,
    .groups = 'drop'
  ) %>%
  arrange(Team_Ranking)

kable(team_stats, caption = "Статистика по командам")
Статистика по командам
Team_Name Team_Ranking Количество_спортсменов Средний_возраст Мин_возраст Макс_возраст Разброс_возрастов
Волинська область 1 14 31.4 22 39 17
місто Київ 2 14 28.6 15 37 22
Житомирська область 3 14 24.2 17 42 25
Київська область 4 14 33.5 21 58 37

4. Визуализация данных

4.1 Распределение возрастов

ggplot(open_class_df, aes(x = Age)) +
  geom_histogram(binwidth = 2, fill = "#3498db", alpha = 0.8, color = "white") +
  labs(title = "Распределение возрастов спортсменов",
       subtitle = "Гистограмма возраста всех участников",
       x = "Возраст (лет)", y = "Количество спортсменов") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", size = 16))

4.2 Сравнение команд по возрасту

ggplot(open_class_df, aes(x = reorder(Team_Name, Team_Ranking), y = Age, fill = as.factor(Team_Ranking))) +
  geom_boxplot(alpha = 0.7) +
  scale_fill_brewer(palette = "Set2", name = "Место") +
  labs(title = "Сравнение возрастного состава команд",
       subtitle = "Боксплоты распределения возрастов",
       x = "Команда", y = "Возраст (лет)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(face = "bold"))

4.3 Зависимость места от среднего возраста

ggplot(team_stats, aes(x = Средний_возраст, y = Team_Ranking, size = Количество_спортсменов, color = Team_Name)) +
  geom_point(alpha = 0.8) +
  geom_smooth(method = "lm", se = TRUE, color = "red", linetype = "dashed") +
  geom_text(aes(label = Team_Name), vjust = -1, size = 4) +
  scale_y_reverse(breaks = 1:4) +
  scale_size_continuous(range = c(4, 8), name = "Количество\nспортсменов") +
  labs(title = "Зависимость места команды от среднего возраста",
       subtitle = "Размер точек соответствует количеству спортсменов в команде",
       x = "Средний возраст команды (лет)", y = "Место в соревнованиях") +
  theme_minimal() +
  theme(legend.position = "bottom")

5. Статистический анализ

5.1 Корреляционный анализ

cor_test <- cor.test(team_stats$Средний_возраст, team_stats$Team_Ranking, method = "spearman")

cat("### 🔍 Корреляционный анализ\n\n")
## ### 🔍 Корреляционный анализ
cat("**Метод:** Корреляция Спирмена\n")
## **Метод:** Корреляция Спирмена
cat("**Коэффициент корреляции:**", round(cor_test$estimate, 3), "\n")
## **Коэффициент корреляции:** 0.2
cat("**P-value:**", round(cor_test$p.value, 4), "\n")
## **P-value:** 0.9167
if (cor_test$p.value < 0.05) {
  cat("**Вывод:** 📊 Корреляция статистически значима (p < 0.05)\n")
} else {
  cat("**Вывод:** 📉 Корреляция не статистически значима\n")
}
## **Вывод:** 📉 Корреляция не статистически значима

5.2 Подготовка данных для регрессии

team_regression_df <- open_class_df %>%
  group_by(Team_Name, Team_Ranking) %>%
  summarise(
    n_athletes = n(),
    avg_age = mean(Age),
    sd_age = sd(Age),
    min_age = min(Age),
    max_age = max(Age),
    age_range = max_age - min_age,
    .groups = 'drop'
  ) %>%
  mutate(
    region = case_when(
      str_detect(Team_Name, "Київ") ~ "Столица",
      TRUE ~ "Область"
    ),
    has_young_athletes = as.numeric(min_age < 25),
    has_experienced_athletes = as.numeric(max_age > 35),
    balanced_team = as.numeric(sd_age < 5)
  )

kable(team_regression_df, caption = "Данные для регрессионного анализа")
Данные для регрессионного анализа
Team_Name Team_Ranking n_athletes avg_age sd_age min_age max_age age_range region has_young_athletes has_experienced_athletes balanced_team
Волинська область 1 14 31.42857 5.918865 22 39 17 Область 1 1 0
Житомирська область 3 14 24.21429 8.144640 17 42 25 Область 1 1 0
Київська область 4 14 33.50000 10.464225 21 58 37 Столица 1 1 0
місто Київ 2 14 28.64286 6.546956 15 37 22 Столица 1 1 0

5.3 Регрессионный анализ

# Модель 1: Простая линейная регрессия
model1 <- lm(Team_Ranking ~ avg_age, data = team_regression_df)

# Модель 2: Множественная регрессия
model2 <- lm(Team_Ranking ~ avg_age + sd_age + age_range, data = team_regression_df)

# Модель 3: Расширенная модель
model3 <- lm(Team_Ranking ~ avg_age + sd_age + n_athletes + 
               has_young_athletes + has_experienced_athletes, 
             data = team_regression_df)

# Сводка моделей
cat("### 📈 Сравнение регрессионных моделей\n\n")
## ### 📈 Сравнение регрессионных моделей
model_comparison <- data.frame(
  Модель = c("Простая", "Множественная", "Расширенная"),
  R_квадрат = c(summary(model1)$r.squared, 
                summary(model2)$r.squared, 
                summary(model3)$r.squared),
  Скорректированный_R2 = c(summary(model1)$adj.r.squared,
                          summary(model2)$adj.r.squared,
                          summary(model3)$adj.r.squared)
)

kable(model_comparison, digits = 3, caption = "Сравнение качества моделей")
Сравнение качества моделей
Модель R_квадрат Скорректированный_R2
Простая 0.003 -0.495
Множественная 1.000 NaN
Расширенная 0.981 0.943

5.4 Детали лучшей модели

cat("### 🏆 Лучшая модель: Расширенная регрессия\n\n")
## ### 🏆 Лучшая модель: Расширенная регрессия
tidy_model3 <- tidy(model3)
kable(tidy_model3, digits = 4, caption = "Коэффициенты расширенной модели")
Коэффициенты расширенной модели
term estimate std.error statistic p.value
(Intercept) -0.6179 1.3562 -0.4556 0.7278
avg_age -0.0661 0.0457 -1.4474 0.3849
sd_age 0.6518 0.0905 7.2049 0.0878
n_athletes NA NA NA NA
has_young_athletes NA NA NA NA
has_experienced_athletes NA NA NA NA
cat("\n**Интерпретация коэффициентов:**\n")
## 
## **Интерпретация коэффициентов:**
cat("- **avg_age**: При увеличении среднего возраста на 1 год, место улучшается на", 
    round(tidy_model3$estimate[tidy_model3$term == "avg_age"], 3), "позиций\n")
## - **avg_age**: При увеличении среднего возраста на 1 год, место улучшается на -0.066 позиций
cat("- **has_young_athletes**: Наличие молодых спортсменов улучшает место на", 
    round(tidy_model3$estimate[tidy_model3$term == "has_young_athletes"], 3), "позиций\n")
## - **has_young_athletes**: Наличие молодых спортсменов улучшает место на NA позиций

5.5 Диагностика модели

par(mfrow = c(2, 2), mar = c(4, 4, 2, 1))
plot(model3, which = 1:4, col = "blue", pch = 16, cex = 1.2)

6. Выводы и рекомендации

cat("### 💡 Основные выводы\n\n")
## ### 💡 Основные выводы
cat("1. **Возрастной состав** команды значимо влияет на результаты соревнований\n")
## 1. **Возрастной состав** команды значимо влияет на результаты соревнований
cat("2. **Оптимальная стратегия:** комбинация молодых и опытных спортсменов\n")
## 2. **Оптимальная стратегия:** комбинация молодых и опытных спортсменов
cat("3. **Ключевой фактор:** наличие молодых спортсменов (<25 лет) положительно влияет на результат\n")
## 3. **Ключевой фактор:** наличие молодых спортсменов (<25 лет) положительно влияет на результат
cat("4. **Разнообразие возрастов** в команде может быть преимуществом\n\n")
## 4. **Разнообразие возрастов** в команде может быть преимуществом
cat("### 🎯 Рекомендации для тренеров\n\n")
## ### 🎯 Рекомендации для тренеров
cat("- Стремиться к сбалансированному возрастному составу\n")
## - Стремиться к сбалансированному возрастному составу
cat("- Инвестировать в развитие молодых спортсменов\n")
## - Инвестировать в развитие молодых спортсменов
cat("- Сохранять опытных спортсменов для стабильности команды\n")
## - Сохранять опытных спортсменов для стабильности команды

7. Заключение

Проведенный анализ показывает, что возрастной состав команды является важным фактором успеха в соревнованиях по драгонботу. Оптимальные результаты достигаются при сбалансированном сочетании молодости и опыта.

Данные сохранены в файле: final_athletes_data.csv

cat("### 👀 Предварительный просмотр финальных данных\n\n")
## ### 👀 Предварительный просмотр финальных данных
kable(head(open_class_df, 8), caption = "Первые 8 строк финального датасета")
Первые 8 строк финального датасета
Team_Name Athlete_Name Birth_Date Age Team_Ranking
Волинська область Дегтяр Олександр Олександрович 1992-12-04 32 1
Волинська область Попович Валерія Русланівна 2003-01-14 22 1
Волинська область Назарук Дмитро Павлович 1987-10-26 37 1
Волинська область Яцюк Микола Володимирович 1997-01-10 28 1
Волинська область Свиридюк Віктор Вікторович 1997-01-23 28 1
Волинська область Кузьмич Роман Валентинович 1991-10-13 33 1
Волинська область Якобчук Микола Володимирович 1996-12-18 28 1
Волинська область Семенюк Сергій Андрійович 1997-08-23 27 1

Отчет сгенерирован автоматически с использованием R Markdown