Задание 1-2: Создание датасета и очистка с is.na()
my_vector <- c(10, 25, NA, 15, 30, NA, 42, 55, NA, 18)
print("Исходный датасет (вектор):")
## [1] "Исходный датасет (вектор):"
print(my_vector)
## [1] 10 25 NA 15 30 NA 42 55 NA 18
print("Индексы пропусков (TRUE - пропуск):")
## [1] "Индексы пропусков (TRUE - пропуск):"
print(is.na(my_vector))
## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE
print("Очищенный датасет (без NA):")
## [1] "Очищенный датасет (без NA):"
print(my_vector[!is.na(my_vector)])
## [1] 10 25 15 30 42 55 18
Задание 3: Очистка data.frame с complete.cases()
df <- data.frame(
ID = 1:10,
Value = c(5.1, 6.3, NA, 4.8, 7.2, NA, 5.9, 8.0, NA, 6.6),
Category = c("A", "B", "B", NA, "A", "C", "C", "B", NA, "A"),
Score = c(85, NA, 92, 78, 88, 95, NA, 89, 76, 91),
stringsAsFactors = FALSE
)
print("Исходная таблица данных:")
## [1] "Исходная таблица данных:"
print(df)
## ID Value Category Score
## 1 1 5.1 A 85
## 2 2 6.3 B NA
## 3 3 NA B 92
## 4 4 4.8 <NA> 78
## 5 5 7.2 A 88
## 6 6 NA C 95
## 7 7 5.9 C NA
## 8 8 8.0 B 89
## 9 9 NA <NA> 76
## 10 10 6.6 A 91
complete_rows <- complete.cases(df)
print("Логический вектор полных строк (TRUE - нет пропусков):")
## [1] "Логический вектор полных строк (TRUE - нет пропусков):"
print(complete_rows)
## [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE
clean_df <- df[complete_rows, ]
print("Очищенная таблица данных (только полные строки):")
## [1] "Очищенная таблица данных (только полные строки):"
print(clean_df)
## ID Value Category Score
## 1 1 5.1 A 85
## 5 5 7.2 A 88
## 8 8 8.0 B 89
## 10 10 6.6 A 91
Задание 4: Импьютация с caret (airquality)
library(caret)
library(datasets)
data("airquality")
print("Структура исходного датасета airquality:")
## [1] "Структура исходного датасета airquality:"
str(airquality)
## 'data.frame': 153 obs. of 6 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
print("Количество NA в каждом столбце:")
## [1] "Количество NA в каждом столбце:"
colSums(is.na(airquality))
## Ozone Solar.R Wind Temp Month Day
## 37 7 0 0 0 0
df_for_impute <- airquality[, 1:4]
print("Первые несколько строк данных до импьютации:")
## [1] "Первые несколько строк данных до импьютации:"
head(df_for_impute, 10)
## Ozone Solar.R Wind Temp
## 1 41 190 7.4 67
## 2 36 118 8.0 72
## 3 12 149 12.6 74
## 4 18 313 11.5 62
## 5 NA NA 14.3 56
## 6 28 NA 14.9 66
## 7 23 299 8.6 65
## 8 19 99 13.8 59
## 9 8 19 20.1 61
## 10 NA 194 8.6 69
set.seed(123)
preProc_median <- preProcess(df_for_impute, method = "medianImpute")
df_median_imputed <- predict(preProc_median, df_for_impute)
print("Первые несколько строк после импьютации медианой:")
## [1] "Первые несколько строк после импьютации медианой:"
head(df_median_imputed, 10)
## Ozone Solar.R Wind Temp
## 1 41.0 190 7.4 67
## 2 36.0 118 8.0 72
## 3 12.0 149 12.6 74
## 4 18.0 313 11.5 62
## 5 31.5 205 14.3 56
## 6 28.0 205 14.9 66
## 7 23.0 299 8.6 65
## 8 19.0 99 13.8 59
## 9 8.0 19 20.1 61
## 10 31.5 194 8.6 69
print("Проверка NA после импьютации медианой:")
## [1] "Проверка NA после импьютации медианой:"
colSums(is.na(df_median_imputed))
## Ozone Solar.R Wind Temp
## 0 0 0 0
Задание 5: Обнаружение и удаление выбросов
set.seed(456)
data1 <- c(rnorm(40, mean = 10, sd = 2), 25, 30)
data2 <- c(rnorm(40, mean = 50, sd = 5), 10, 75)
print("Сгенерированные данные (data1):")
## [1] "Сгенерированные данные (data1):"
print(data1)
## [1] 7.312957 11.243551 11.601749 7.222215 8.571286 9.351878 11.381286
## [8] 10.501096 12.014705 11.146469 8.168379 12.622195 11.977453 13.307857
## [15] 7.118390 13.894713 13.473872 10.774967 14.560068 13.075767 9.050792
## [22] 6.565382 7.146339 10.416472 9.928328 12.268569 9.074290 9.343232
## [29] 12.969079 7.821244 8.942412 8.812414 6.002169 10.592306 10.341251
## [36] 13.631305 8.678794 9.719496 9.152042 9.922528 25.000000 30.000000
print("Сгенерированные данные (data2):")
## [1] "Сгенерированные данные (data2):"
print(data2)
## [1] 49.85529 51.96519 48.75193 50.41725 60.39437 50.60426 50.59075 53.85027
## [9] 44.12299 52.04519 46.67525 48.71738 53.39391 54.48422 53.09178 53.65727
## [17] 47.93413 57.78907 52.70849 52.88575 38.72645 45.08970 48.99716 54.47965
## [25] 49.78228 58.23654 57.81650 42.84311 47.27703 46.14373 49.15006 49.79619
## [33] 41.39730 57.22053 49.89993 51.35116 49.43533 45.72556 44.83129 51.11013
## [41] 10.00000 75.00000
remove_outliers <- function(x) {
outliers <- boxplot.stats(x)$out
outlier_indices <- which(x %in% outliers)
if (length(outlier_indices) > 0) {
cat("Найдены выбросы на позициях:", paste(outlier_indices, collapse=", "), "со значениями:", paste(outliers, collapse=", "), "\n")
return(x[-outlier_indices])
} else {
cat("Выбросов не найдено.\n")
return(x)
}
}
par(mfrow=c(1,2))
boxplot(data1, main="Data1 с выбросами", col="lightblue", horizontal=TRUE)
boxplot(data2, main="Data2 с выбросами", col="lightgreen", horizontal=TRUE)

clean_data1 <- remove_outliers(data1)
## Найдены выбросы на позициях: 41, 42 со значениями: 25, 30
clean_data2 <- remove_outliers(data2)
## Найдены выбросы на позициях: 41, 42 со значениями: 10, 75
par(mfrow=c(1,2))
boxplot(clean_data1, main="Data1 без выбросов", col="lightblue", horizontal=TRUE)
boxplot(clean_data2, main="Data2 без выбросов", col="lightgreen", horizontal=TRUE)

par(mfrow=c(1,1))
Задание 6: Удаление дублирующихся строк
df_dup <- data.frame(
ID = c(1, 2, 3, 1, 4, 2, 5, 3),
Value = c("A", "B", "C", "A", "D", "B", "E", "C"),
Score = c(10, 20, 30, 10, 40, 20, 50, 30),
stringsAsFactors = FALSE
)
print("Исходная таблица с дубликатами:")
## [1] "Исходная таблица с дубликатами:"
print(df_dup)
## ID Value Score
## 1 1 A 10
## 2 2 B 20
## 3 3 C 30
## 4 1 A 10
## 5 4 D 40
## 6 2 B 20
## 7 5 E 50
## 8 3 C 30
df_unique <- unique(df_dup)
print("Результат unique() (все уникальные строки):")
## [1] "Результат unique() (все уникальные строки):"
print(df_unique)
## ID Value Score
## 1 1 A 10
## 2 2 B 20
## 3 3 C 30
## 5 4 D 40
## 7 5 E 50
print(paste("Количество строк после unique():", nrow(df_unique)))
## [1] "Количество строк после unique(): 5"
duplicate_rows <- duplicated(df_dup)
print("Логический вектор duplicated() (TRUE - дубликат):")
## [1] "Логический вектор duplicated() (TRUE - дубликат):"
print(duplicate_rows)
## [1] FALSE FALSE FALSE TRUE FALSE TRUE FALSE TRUE
df_dup_removed <- df_dup[!duplicate_rows, ]
print("Результат !duplicated() (первые вхождения каждой уникальной строки):")
## [1] "Результат !duplicated() (первые вхождения каждой уникальной строки):"
print(df_dup_removed)
## ID Value Score
## 1 1 A 10
## 2 2 B 20
## 3 3 C 30
## 5 4 D 40
## 7 5 E 50
print(paste("Количество строк после !duplicated():", nrow(df_dup_removed)))
## [1] "Количество строк после !duplicated(): 5"
duplicate_rows_last <- duplicated(df_dup, fromLast = TRUE)
df_dup_removed_last <- df_dup[!duplicate_rows_last, ]
print("Результат !duplicated(..., fromLast=TRUE) (последние вхождения каждой уникальной строки):")
## [1] "Результат !duplicated(..., fromLast=TRUE) (последние вхождения каждой уникальной строки):"
print(df_dup_removed_last)
## ID Value Score
## 4 1 A 10
## 5 4 D 40
## 6 2 B 20
## 7 5 E 50
## 8 3 C 30
print("Сравнение:")
## [1] "Сравнение:"
print("unique() сохранил порядок первого появления каждой уникальной строки, удалив все повторы.")
## [1] "unique() сохранил порядок первого появления каждой уникальной строки, удалив все повторы."
print("!duplicated() сделал то же самое, что и unique() по умолчанию.")
## [1] "!duplicated() сделал то же самое, что и unique() по умолчанию."
print("!duplicated(fromLast=TRUE) сохранил порядок последнего появления каждой уникальной строки.")
## [1] "!duplicated(fromLast=TRUE) сохранил порядок последнего появления каждой уникальной строки."
Задание 7: Обработка пропусков с MICE
library(mice)
data("airquality")
df_mice_clean <- airquality[, 1:4]
names(df_mice_clean) <- c("Ozone", "Solar", "Wind", "Temp")
print("Датасет airquality для анализа:")
## [1] "Датасет airquality для анализа:"
head(df_mice_clean, 15)
## Ozone Solar Wind Temp
## 1 41 190 7.4 67
## 2 36 118 8.0 72
## 3 12 149 12.6 74
## 4 18 313 11.5 62
## 5 NA NA 14.3 56
## 6 28 NA 14.9 66
## 7 23 299 8.6 65
## 8 19 99 13.8 59
## 9 8 19 20.1 61
## 10 NA 194 8.6 69
## 11 7 NA 6.9 74
## 12 16 256 9.7 69
## 13 11 290 9.2 66
## 14 14 274 10.9 68
## 15 18 65 13.2 58
print("Сводка по пропускам:")
## [1] "Сводка по пропускам:"
summary(df_mice_clean)
## Ozone Solar Wind Temp
## Min. : 1.00 Min. : 7.0 Min. : 1.700 Min. :56.00
## 1st Qu.: 18.00 1st Qu.:115.8 1st Qu.: 7.400 1st Qu.:72.00
## Median : 31.50 Median :205.0 Median : 9.700 Median :79.00
## Mean : 42.13 Mean :185.9 Mean : 9.958 Mean :77.88
## 3rd Qu.: 63.25 3rd Qu.:258.8 3rd Qu.:11.500 3rd Qu.:85.00
## Max. :168.00 Max. :334.0 Max. :20.700 Max. :97.00
## NA's :37 NA's :7
md.pattern(df_mice_clean)

## Wind Temp Solar Ozone
## 111 1 1 1 1 0
## 35 1 1 1 0 1
## 5 1 1 0 1 1
## 2 1 1 0 0 2
## 0 0 7 37 44
mice_imputed <- mice(df_mice_clean, m = 5, maxit = 20, method = 'pmm', seed = 123, printFlag = FALSE)
print("Результат импьютации MICE:")
## [1] "Результат импьютации MICE:"
print(mice_imputed)
## Class: mids
## Number of multiple imputations: 5
## Imputation methods:
## Ozone Solar Wind Temp
## "pmm" "pmm" "" ""
## PredictorMatrix:
## Ozone Solar Wind Temp
## Ozone 0 1 1 1
## Solar 1 0 1 1
## Wind 1 1 0 1
## Temp 1 1 1 0
df_complete_1 <- complete(mice_imputed, 1)
print("Заполненный датасет (импьютация №1):")
## [1] "Заполненный датасет (импьютация №1):"
head(df_complete_1, 20)
## Ozone Solar Wind Temp
## 1 41 190 7.4 67
## 2 36 118 8.0 72
## 3 12 149 12.6 74
## 4 18 313 11.5 62
## 5 1 224 14.3 56
## 6 28 175 14.9 66
## 7 23 299 8.6 65
## 8 19 99 13.8 59
## 9 8 19 20.1 61
## 10 23 194 8.6 69
## 11 7 7 6.9 74
## 12 16 256 9.7 69
## 13 11 290 9.2 66
## 14 14 274 10.9 68
## 15 18 65 13.2 58
## 16 14 334 11.5 64
## 17 34 307 12.0 66
## 18 6 78 18.4 57
## 19 30 322 11.5 68
## 20 11 44 9.7 62
print("Проверка NA после импьютации:")
## [1] "Проверка NA после импьютации:"
print(colSums(is.na(df_complete_1)))
## Ozone Solar Wind Temp
## 0 0 0 0
Задание 8: Диагностика мультиколлинеарности
library(car)
library(GGally)
set.seed(101)
n <- 100
x1 <- rnorm(n, mean = 50, sd = 10)
x2 <- rnorm(n, mean = 30, sd = 5)
x3 <- 0.9 * x2 + rnorm(n, mean = 0, sd = 2)
x4 <- rnorm(n, mean = 100, sd = 15)
y <- 5 + 0.4 * x1 + 0.8 * x2 + 0.1 * x3 + 1.5 * x4 + rnorm(n, mean = 0, sd = 10)
df_ml <- data.frame(y = y, x1 = x1, x2 = x2, x3 = x3, x4 = x4)
print("Матрица корреляций:")
## [1] "Матрица корреляций:"
cor_matrix <- cor(df_ml[, -1])
print(round(cor_matrix, 2))
## x1 x2 x3 x4
## x1 1.00 0.11 0.09 -0.15
## x2 0.11 1.00 0.94 0.18
## x3 0.09 0.94 1.00 0.19
## x4 -0.15 0.18 0.19 1.00
ggpairs(df_ml[, -1], title = "Матрица корреляций")

model <- lm(y ~ x1 + x2 + x3 + x4, data = df_ml)
print("Сводка регрессионной модели:")
## [1] "Сводка регрессионной модели:"
summary(model)
##
## Call:
## lm(formula = y ~ x1 + x2 + x3 + x4, data = df_ml)
##
## Residuals:
## Min 1Q Median 3Q Max
## -19.610 -6.749 -1.128 6.444 22.805
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.48486 9.76915 0.050 0.96052
## x1 0.38135 0.10756 3.546 0.00061 ***
## x2 1.34961 0.57644 2.341 0.02131 *
## x3 -0.35769 0.57069 -0.627 0.53231
## x4 1.49225 0.06447 23.145 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 9.787 on 95 degrees of freedom
## Multiple R-squared: 0.8696, Adjusted R-squared: 0.8641
## F-statistic: 158.4 on 4 and 95 DF, p-value: < 2.2e-16
vif_values <- vif(model)
print("VIF (Variance Inflation Factor):")
## [1] "VIF (Variance Inflation Factor):"
print(vif_values)
## x1 x2 x3 x4
## 1.043238 8.658105 8.667380 1.069558
if (any(vif_values > 10)) {
cat("Обнаружена сильная мультиколлинеарность для переменных с VIF > 10.\n")
}
model_corrected <- lm(y ~ x1 + x2 + x4, data = df_ml)
print("Сводка модели после удаления x3:")
## [1] "Сводка модели после удаления x3:"
summary(model_corrected)
##
## Call:
## lm(formula = y ~ x1 + x2 + x4, data = df_ml)
##
## Residuals:
## Min 1Q Median 3Q Max
## -18.6771 -6.7193 -0.9819 6.4118 22.6183
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.20039 9.67149 0.124 0.901482
## x1 0.38200 0.10721 3.563 0.000573 ***
## x2 1.01101 0.20044 5.044 2.15e-06 ***
## x4 1.48972 0.06414 23.224 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 9.756 on 96 degrees of freedom
## Multiple R-squared: 0.869, Adjusted R-squared: 0.865
## F-statistic: 212.4 on 3 and 96 DF, p-value: < 2.2e-16
print("VIF для новой модели:")
## [1] "VIF для новой модели:"
print(vif(model_corrected))
## x1 x2 x4
## 1.043142 1.053546 1.065360