Вопрос или проблема
Я пытаюсь использовать функцию missForest() из библиотеки ‘missForest’, но постоянно получаю одно и то же сообщение об ошибке.
Вот код:
библиотеки:
library(dplyr)
library(naniar)
library(missForest)
данные:
url <- 'https://archive.ics.uci.edu/ml/machine-learning-databases/credit-screening/crx.data'
crx <- read.csv(url, sep = ",", header = F)
Затем я заменяю все “?” на нулевые значения (NA):
crx <- crx %>% replace_with_na_all(condition = ~.x == "?")
А затем я применяю missForest, чтобы избавиться от нулевых значений:
crx <- missForest(crx)
И я получаю следующее сообщение об ошибке:
Error: Assigned data `mean(xmis[, t.co], na.rm = TRUE)` must be
compatible with existing data. ℹ Error occurred for column `V1`. x Can't convert <double> to <character>. Run `rlang::last_error()` to see where the error occurred.
20.
stop(fallback)
19.
signal_abort(cnd)
18.
cnd_signal(error_assign_incompatible_type(x, value, j, value_arg, cnd_message(cnd)))
17.
(function (cnd) { cnd_signal(error_assign_incompatible_type(x, value, j, value_arg, cnd_message(cnd))) ...
16.
signalCondition(cnd)
15.
signal_abort(cnd)
14.
abort(message, class = c(class, "vctrs_error"), ...)
13.
stop_vctrs(message, class = c(class, "vctrs_error_incompatible"), x = x, y = y, details = details, ...)
12.
stop_incompatible(x, y, x_arg = x_arg, y_arg = y_arg, details = details, ..., message = message, class = c(class, "vctrs_error_incompatible_type"))
11.
stop_incompatible_type(x = x, y = to, ..., x_arg = x_arg, y_arg = to_arg, action = "convert", details = details, message = message, class = class)
10.
stop_incompatible_cast(x, to, x_arg = x_arg, to_arg = to_arg, `vctrs:::from_dispatch` = match_from_dispatch(...))
9.
vec_default_cast(x = x, to = to, x_arg = x_arg, to_arg = to_arg, `vctrs:::from_dispatch` = `vctrs:::from_dispatch`, `vctrs:::df_fallback` = `vctrs:::df_fallback`, `vctrs:::s3_fallback` = `vctrs:::s3_fallback`)
8.
(function () vec_default_cast(x = x, to = to, x_arg = x_arg, to_arg = to_arg, `vctrs:::from_dispatch` = `vctrs:::from_dispatch`, `vctrs:::df_fallback` = `vctrs:::df_fallback`, `vctrs:::s3_fallback` = `vctrs:::s3_fallback`))()
7.
`vec_slice<-`(`*tmp*`, i, value = value[[j]])
6.
withCallingHandlers(for (j in seq_along(x)) { xj <- x[[j]] vec_slice(xj, i) <- value[[j]] x[[j]] <- xj ...
5.
tbl_subassign_row(xj, i, value, value_arg)
4.
tbl_subassign(x, i, j, value, i_arg, j_arg, substitute(value))
3.
`[<-.tbl_df`(`*tmp*`, is.na(xmis[, t.co]), t.co, value = NA_real_)
2.
`[<-`(`*tmp*`, is.na(xmis[, t.co]), t.co, value = NA_real_)
1.
missForest(crx)
Show in New WindowClear OutputExpand/Collapse Output
tibble [690 × 16] (S3: tbl_df/tbl/data.frame)
$ V1 : chr [1:690] "b" "a" "a" "b" ...
$ V2 : chr [1:690] "30.83" "58.67" "24.50" "27.83" ...
$ V3 : num [1:690] 0 4.46 0.5 1.54 5.62 ...
$ V4 : chr [1:690] "u" "u" "u" "u" ...
$ V5 : chr [1:690] "g" "g" "g" "g" ...
$ V6 : chr [1:690] "w" "q" "q" "w" ...
$ V7 : chr [1:690] "v" "h" "h" "v" ...
$ V8 : num [1:690] 1.25 3.04 1.5 3.75 1.71 ...
$ V9 : chr [1:690] "t" "t" "t" "t" ...
$ V10: chr [1:690] "t" "t" "f" "t" ...
$ V11: int [1:690] 1 6 0 5 0 0 0 0 0 0 ...
$ V12: chr [1:690] "f" "f" "f" "t" ...
$ V13: chr [1:690] "g" "g" "g" "g" ...
$ V14: chr [1:690] "00202" "00043" "00280" "00100" ...
$ V15: int [1:690] 0 560 824 3 0 0 31285 1349 314 1442 ...
$ V16: chr [1:690] "+" "+" "+" "+" ...
Я читал на StackOverflow вероятное решение этой проблемы: преобразовать данные в датафрейм с помощью функции as.data.frame(), но это тоже не помогло, и вернуло следующее сообщение об ошибке:
argument is not numeric or logical: returning NAargument is not numeric or logical:
returning NAargument is not numeric or logical: returning NAargument is not numeric or
logical: returning NAargument is not numeric or logical: returning NAargument is not numeric
or logical: returning NAargument is not numeric or logical: returning NAargument is not
numeric or logical: returning NAargument is not numeric or logical: returning NAargument is
not numeric or logical: returning NAargument is not numeric or logical: returning NA missForest iteration 1 in progress...done!
Error in FUN(left, right) : non-numeric argument to binary operator
Во-первых, я не понимаю, зачем вы используете пакет naniar
для такой простой задачи, как замена значений. Вы можете использовать очень простой метод для замены значений.
После того как вы получили данные, просто используйте это для замены ? значений в ваших данных –
> crx = as.data.frame(crx)
> crx[crx == '?'] <- NA # Заменить ? значения на NA
Вы увидите сводку, подобную этой –
> summary(crx)
V1 V2 V3 V4 V5 V6 V7 V8 V9
? : 0 22.67 : 9 Min. : 0.000 ? : 0 ? : 0 c :137 v :399 Min. : 0.000 f:329
a :210 20.42 : 7 1st Qu.: 1.000 l : 2 g :519 q : 78 h :138 1st Qu.: 0.165 t:361
b :468 18.83 : 6 Median : 2.750 u :519 gg : 2 w : 64 bb : 59 Median : 1.000
NA's: 12 19.17 : 6 Mean : 4.759 y :163 p :163 i : 59 ff : 57 Mean : 2.223
20.67 : 6 3rd Qu.: 7.207 NA's: 6 NA's: 6 aa : 54 j : 8 3rd Qu.: 2.625
(Other):644 Max. :28.000 (Other):289 (Other): 20 Max. :28.500
NA's : 12 NA's : 9 NA's : 9
V10 V11 V12 V13 V14 V15 V16
f:395 Min. : 0.0 f:374 g:625 00000 :132 Min. : 0.0 -:383
t:295 1st Qu.: 0.0 t:316 p: 8 00120 : 35 1st Qu.: 0.0 +:307
Median : 0.0 s: 57 00200 : 35 Median : 5.0
Mean : 2.4 00160 : 34 Mean : 1017.4
3rd Qu.: 3.0 00080 : 30 3rd Qu.: 395.5
Max. :67.0 (Other):411 Max. :100000.0
NA's : 13
Запустите функцию str
, чтобы получить представление о значениях переменных –
> str(crx)
'data.frame': 690 obs. of 16 variables:
$ V1 : Factor w/ 3 levels "?","a","b": 3 2 2 3 3 3 3 2 3 3 ...
$ V2 : Factor w/ 350 levels "?","13.75","15.17",..: 158 330 91 127 45 170 181 76 312 257 ...
$ V3 : num 0 4.46 0.5 1.54 5.62 ...
$ V4 : Factor w/ 4 levels "?","l","u","y": 3 3 3 3 3 3 3 3 4 4 ...
$ V5 : Factor w/ 4 levels "?","g","gg","p": 2 2 2 2 2 2 2 2 4 4 ...
$ V6 : Factor w/ 15 levels "?","aa","c","cc",..: 14 12 12 14 14 11 13 4 10 14 ...
$ V7 : Factor w/ 10 levels "?","bb","dd",..: 9 5 5 9 9 9 5 9 5 9 ...
$ V8 : num 1.25 3.04 1.5 3.75 1.71 ...
$ V9 : Factor w/ 2 levels "f","t": 2 2 2 2 2 2 2 2 2 2 ...
$ V10: Factor w/ 2 levels "f","t": 2 2 1 2 1 1 1 1 1 1 ...
$ V11: int 1 6 0 5 0 0 0 0 0 0 ...
$ V12: Factor w/ 2 levels "f","t": 1 1 1 2 1 2 2 1 1 2 ...
$ V13: Factor w/ 3 levels "g","p","s": 1 1 1 1 3 1 1 1 1 1 ...
$ V14: Factor w/ 171 levels "?","00000","00017",..: 70 13 98 33 39 117 56 25 64 17 ...
$ V15: int 0 560 824 3 0 0 31285 1349 314 1442 ...
$ V16: Factor w/ 2 levels "-","+": 2 2 2 2 2 2 2 2 2 2 ...
Здесь вы видите, что ваши столбцы V2 и V14 имеют более 53 уровней (категорий). Метод случайного леса не может использоваться с переменными, имеющими более 53 категорий. Поэтому вы не можете использовать их в missForest. Если вы используете, вы получите ошибку следующего вида –
Error in randomForest.default(x = obsX, y = obsY, ntree = ntree, mtry = mtry, :
Can not handle categorical predictors with more than 53 categories.
Таким образом, ваш вариант – использовать другие переменные, кроме этих двух.
> crx_impute = missForest(crx[,c(1,3,4,5,6,7,8,9,10,11,12,13,15,16)])
Затем вы можете использовать crx_impute$ximp
, чтобы получить свои интерполированные данные.
Ответ или решение
Вопрос использования функции missForest()
из библиотеки missForest
в R часто вызывает сложности у пользователей, особенно когда дело касается корректной обработки данных. Рассмотрим основные причины, по которым может возникать ошибка, и предоставим решение.
Обработка данных
В вашем коде данные загружаются с помощью:
url <- 'https://archive.ics.uci.edu/ml/machine-learning-databases/credit-screening/crx.data'
crx <- read.csv(url, sep = ",", header = FALSE)
Этот этап загрузки является корректным. Однако, вы заменяете значения "?" на NA
с использованием naniar
, что можно сделать и более простым способом:
crx[crx == '?'] <- NA
Проверка структуры данных
Для корректного функционирования missForest
важно удостовериться, что данные имеют правильный формат. Используйте функцию str()
для проверки структуры вашего датафрейма:
str(crx)
Ошибки при выполнении функции
Ошибка, которую вы получаете, указывает на проблему с типами данных в ваших переменных. Функция missForest
не может обрабатывать факторы с более чем 53 уровнями. Вы должны выявить такие столбцы, например:
V2
(содержит слишком много категорий)V14
(тоже имеет большое количество категорий)
Эти факторы могут вызывать сбои в работе алгоритма, так как randomForest
не справляется с переменными, имеющими большое количество уникальных значений.
Решения
Для устранения проблемы вам нужно выполнить следующие шаги:
- Исключите проблемные столбцы: Примените
missForest
, исключив колонки с факторами более 53 уровней:
crx_impute <- missForest(crx[, c(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16)])
- Получите результаты: После выполнения функции вы можете получить импутированные данные через:
imputed_data <- crx_impute$ximp
Заключение
При использовании функции missForest
необходимо обращать внимание на типы данных и количество уникальных значений в ваших факторах. Эффективное управление данными, включая удаление или изменение проблемных столбцов, поможет избежать ошибок и обеспечить корректную работу функции. Понимание этого аспекта тотчас повысит качество вашей обработки данных и упростит выполнение анализа.
Если у вас возникли дополнительные вопросы или вы столкнулись с новыми ошибками, не стесняйтесь обращаться за помощью.