R устанавливает значение по умолчанию для отсутствующего значения коэффициента - PullRequest
0 голосов
/ 18 мая 2018

Я часто работаю с formula объектами и обнаружил, что очень удобно преобразовывать дискретные переменные в факторы.Предположим следующий пример:

library(caret); library(data.table); data("iris"); iris <- as.data.table(iris)
dummy <- dummyVars(~ -1 + factor(Species, 
                                 levels = c("setosa", "versicolor", "virginica")
                                 ), data = iris)
predict(dummy, newdata = iris[1,])

, который возвращает правильный кадр, как и ожидалось.

Мой вопрос:

Если задан новый неопределенный уровень Species, множитель возвращает NA, в то же время дополнительно портя окончательный результат:

predict(dummy, newdata = iris[1,][, Species:= "something_undefined"])

Однако в некоторых случаях полезно заменить новые метки в качестве значения по умолчанию, т.е. типичная / медианная метка вместо NA.Один из возможных способов, который я мог бы придумать, - написать собственную функцию custom.na.impute для работы с такими значениями и использовать ее по умолчанию na.action, то есть

predict(dummy, newdata = iris[1,][, Species:= "something_undefined"], 
        na.action = custom.na.impute)

Однако, если я правильно понимаю, здесь яЯ должен был бы вручную написать правила для всех различных факторов и обновить их с включением новых факторов. Вместо этого я ищу что-то вроде этого :

factor(Species, levels = c("setosa", "versicolor", "virginica"),
                na.value = "setosa")

То есть, чтобы иметь возможность определить значение по умолчанию / отсутствует для любого factor и указать его непосредственно в формулеобъект, без необходимости возиться с кастомами na.actions.

Любые идеи / предложения будут оценены!

1 Ответ

0 голосов
/ 30 мая 2018

Комментируя свой вопрос, так как я не смог найти более чистого / реализованного решения в существующем пакете.Но это может быть полезно для кого-то.

В любом случае, лучшее решение по-прежнему приветствуется!

Решением было изменить существующую функцию factor следующим образом:

factor2 <- function (x = character(), levels, labels = levels, exclude = NA, 
          ordered = is.ordered(x), nmax = NA, default = NA) 
{
  # --- Added rows
  if(!is.na(default)){
    levels <- unique(c(levels, default))
  }
  # ---

  if (is.null(x)) 
    x <- character()
  nx <- names(x)
  if (missing(levels)) {
    y <- unique(x, nmax = nmax)
    ind <- sort.list(y)
    y <- as.character(y)
    levels <- unique(y[ind])
  }
  force(ordered)
  exclude <- as.vector(exclude, typeof(x))
  x <- as.character(x)
  levels <- levels[is.na(match(levels, exclude))]

  # --- Modified rows
  f <- match(x, levels, nomatch = which(levels == default)[1])
  # ---

  if (!is.null(nx)) 
    names(f) <- nx
  nl <- length(labels)
  nL <- length(levels)
  if (!any(nl == c(1L, nL))) 
    stop(gettextf("invalid 'labels'; length %d should be 1 or %d", 
                  nl, nL), domain = NA)
  levels(f) <- if (nl == nL) 
    as.character(labels)
  else paste0(labels, seq_along(levels))
  class(f) <- c(if (ordered) "ordered", "factor")
  f
}

Теперь значение default либо добавляется как новый уровень, либо сопоставление корректируется, когда новое значение не равно levels.

Теперь прогноз работает так, как задумано:

dummy <- dummyVars(~ -1 + factor2(Species, 
                                 levels = c("setosa", "versicolor", "virginica"),
                                 default = "versicolor"
), data = iris)

Прогноз возвращает правильный уровень по умолчанию без каких-либо изменений кода:

predict(dummy, newdata = iris[1,][, Species:= "something_undefined"])

Примечание: вместо factor2, assignInNamespace('factor', factor2, 'base') тоже должны работать, хотя это более навязчиво.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...