Замена фактора преобразуется в символ в R

Я хочу заменить NA в выбранных столбцах на последнее значение в уровнях столбца, но он продолжает преобразовывать столбец в символ:

table(sapply(cop2014, class))

factor   numeric
400      116

varToCat = c("V21A","A3","Escolari","A17","B8","C5B","RamaEmpPri","C11","C16B",
         "C16C","D4B","D4C","RamaEmpSec","RamaUltEmpCesant","G12",
         "RamaFuerzaTrab","OcupFuerzaTrab","ActNoMer")

cop2014[,varToCat] = sapply(cop2014[,varToCat], 
        function(col) replace(col, is.na(col), last(levels(col))))

Когда я смотрю на классы моих переменных, я вижу, что они изменились.

table(sapply(cop2014, class))

character   factor   numeric
18          382      116

Любой намек на то, почему это происходит? Я только хочу заменить NA с действительным фактором (в этом случае последний на уровнях)

1 ответ

Решение

Это случай преобразования в matrix с sapply и matrix может содержать только один класс. Итак, вместо sapplyиспользовать lapply

df1[] <- lapply(df1, function(x) replace(x, is.na(x), last(levels(x))))
str(df1)
#'data.frame':   10 obs. of  2 variables:
#$ v1: Factor w/ 3 levels "B","D","E": 1 1 3 2 2 3 1 3 3 1
#$ v2: Factor w/ 5 levels "A","B","C","D",..: 4 3 5 5 2 5 2 1 4 1

Если мы посмотрим на вывод sapply, это matrix и он может содержать только один класс. Во время преобразования в matrixатрибуты factor теряются, и он преобразуется в character

sapply(df1, function(x) replace(x, is.na(x), last(levels(x))))
#      v1  v2 
# [1,] "B" "D"
# [2,] "B" "C"
# [3,] "E" "E"
# [4,] "D" "E"
# [5,] "D" "B"
# [6,] "E" "E"
# [7,] "B" "B"
# [8,] "E" "A"
# [9,] "E" "D"
#[10,] "B" "A"

В дополнение к lapplyмы также можем использовать mutate_at от tidyverse

library(dplyr)  
cop2014 %>%
  mutate_at(vars(varToCat), funs(replace(., is.na(.), last(levels(.)))))

данные

f1 <- function(n) sample(c(LETTERS[1:5], NA), n, replace = TRUE)
set.seed(24)
df1 <- data.frame(v1 = f1(10), v2 = f1(10))
Другие вопросы по тегам