Могу ли я написать функцию для переоценки уровней фактора? - PullRequest
1 голос
/ 20 апреля 2020

В моем фрейме данных есть столбец «lg_with_children», который имеет 5 уровней: «Половина и половина», «Мандарин», «Шанхайский», «Другое», «Не применимо» и «Не важно». Я хочу сократить 5 уровней до 2 уровней, «Шанхайский» и «Другой».

Для этого я использовал функцию revalue () из пакета plyr, чтобы успешно переименовать уровни. Я использовал приведенный ниже код, и он работал нормально.

data$lg_with_children <- revalue(data$lg_with_children,
                             c("Mandarin" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
                             c("Half and half" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
                             c("N/A" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
                             c("Not important" = "Other"))

Чтобы немного сжать код, я вернулся к данным, прежде чем переоценил уровни и попытался написать функцию. Я попробовал следующее после исследования того, как писать свои собственные функции (я довольно нов в этом).

revalue_factor_levels <- function(df, col, source, target) {df$col <- revalue(df$col, c("source" = "target"))}

Я намеренно оставил df, col, source и target generi c, потому что Мне нужно переоценить некоторые другие столбцы таким же образом.

Затем я попытался запустить код, заполняющий аргументы, и получил следующее сообщение:

предупреждение

Я не совсем уверен, что проблема есть. Я попробовал следующую настройку кода, но ничего не получилось.

revalue_factor_levels <- function(df, col, source, target) {df$col <- revalue(df$col, c(source = target))}

Любое руководство приветствуется. Благодаря.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Вы можете написать свою функцию для перекодирования уровней - самый простой способ сделать это, вероятно, изменить уровни напрямую с помощью levels(fac) <- list(new_lvl1 = c(old_lvl1, old_lvl2), new_lvl2 = c(old_lvl3, old_lvl4))

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

Извлечение fct_recode из пакета forcats. Ссылка для выполнения c.

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

Теперь о том, почему ваш код не ' t работает:

  • df$col ищет столбец с буквальным названием col. Обходной путь должен сделать df[[col]] вместо.
  • Не забудьте вернуть df в конце вашей функции
  • c(source = target) создаст вектор с одним элементом с именем "source" независимо от того, что происходит в переменной source. Решение состоит в том, чтобы создать вектор c(source = target) в 2 этапа.
revalue_factor_levels <- function(df, col, source, target) {
  to_rename <- target
  names(to_rename) <- source
  df[[col]] <- revalue(df[[col]], to_rename)
  df
}

Возврат df означает, что синтаксис:

data <- revalue_factor_levels(data, "lg_with_children", "Mandarin", "Other")

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

library(dplyr)

data <- data %>%
  revalue_factor_levels("lg_with_children", "Mandarin", "Other") %>%
  revalue_factor_levels("lg_with_children", "Half and half", "Other") %>%
  revalue_factor_levels("lg_with_children", "N/A", "Other")

Тем не менее, использование forcats проще и менее подвержено взлому в крайних случаях.

Редактировать:

Ничто не мешает вам использовать forcats и создавать собственные функции. Например, это ближе к тому, что вы хотите достичь:

revalue_factor_levels <- function(df, col, ref_level) {
  df[[col]] <- forcats::fct_others(df[[col]], keep = ref_level)
  df
}

# Will keep Shanghaisese and revalue other levels to "Other". 
data <- revalue_factor_levels(data, "lg_with_children", "Shanghainese")
0 голосов
/ 20 апреля 2020

Вот чем я закончил благодаря помощи сообщества.

revalue_factor_levels <- function(df, col, ref_level) {
  df[[col]] <- fct_other(df[[col]], keep = ref_level)
  df
}

data <- revalue_factor_levels(data, "lg_with_children", "Shanghainese")
...