Для циклического преобразования NA в факторных переменных в «Нет»

#r

Вопрос:

Я хочу преобразовать NAs в моих факторных переменных в строку «Нет», которая будет уровнем в моем наборе данных.

я пытался

 for ( col in 1:ncol(data)){
  class(data$col) == "factor"
  data$col = addNA(data$col)
  levels(data$col) <- c(levels(data$col), "None")
  print(summary(data))
}
 

И я получил эту ошибку

 Unknown or uninitialised column: `col`.Unknown or uninitialised column: `col`.Error: Assigned data `addNA(cdata$col)` must be compatible with existing data.
x Existing data has 1000 rows.
x Assigned data has 0 rows.
i Only vectors of size 1 are recycled.
 

В чем же проблема в таком случае?
Какой лучший способ сделать это для всех столбцов факторов сразу, а не для каждого столбца в отдельности?

Ответ №1:

Мы можем зациклить across столбцы , которые есть factor , преобразовать NA в «Нет», используя fct_explicit_na из forcats

 library(dplyr)
library(forcats)
data <- data %>%
     mutate(across(where(is.factor), ~ fct_explicit_na(., na_level = "None")))
 

В for цикле существует несколько проблем

  1. class(data$col) == "factor" проверяется, но это должно быть внутри if(...) выражения
  2. data$col — неверно, так как нет имен столбцов с именем col as, вместо этого это было бы data[[col]]
  3. summary(data) можно проверить вне for цикла
 for (col in seq_along(data)){
  if(class(data[[col]]) == "factor") {
     data[[col]] = addNA(data[[col]])
     levels(data[[col]]) <- c(levels(data[[col]]), "None")    
   }
}

print(summary(data))
 

Ответ №2:

Вот альтернативный способ:

  1. определите, какие столбцы являются фактором
  2. Добавьте «Нет» к уровням каждого фактора
  3. Замените NA на «Нет».:

Вот пример с макетом набора данных:

 # identify which is factor column
x <-  sapply(df, is.factor) 

df[, x] <- lapply(df[, x], function(.){
    levels(.) <- c(levels(.), "None")
    replace(., is.na(.), "None")
})
 

выход:

   a     b         c
  <fct> <fct> <dbl>
1 1     None      2
2 None  3        NA
3 4     None     NA
 

данные:

 df <- structure(list(a = structure(c(1L, NA, 2L), .Label = c("1", "4"
), class = "factor"), b = structure(c(NA, 1L, NA), .Label = "3", class = "factor"), 
c = c(2, NA, NA)), row.names = c(NA, -3L), class = c("tbl_df", 
"tbl", "data.frame"))