Почему as.factor возвращает символ при использовании внутри применяются?

Я хочу преобразовать переменные в использование факторов apply():

a <- data.frame(x1 = rnorm(100),
                x2 = sample(c("a","b"), 100, replace = T),
                x3 = factor(c(rep("a",50) , rep("b",50))))

a2 <- apply(a, 2,as.factor)
apply(a2, 2,class)

результаты в:

         x1          x2          x3 
"character" "character" "character" 

Я не понимаю, почему это приводит к символьным векторам вместо факторных векторов.

13
задан MERose 8 December 2015 в 14:22
поделиться

1 ответ

apply преобразует ваш data.frame в символьную матрицу. Используйте lapply :

lapply(a, class)
# $x1
# [1] "numeric"
# $x2
# [1] "factor"
# $x3
# [1] "factor"

Во второй команде apply преобразует результат в матрицу символов, используя lapply :

a2 <- lapply(a, as.factor)
lapply(a2, class)
# $x1
# [1] "factor"
# $x2
# [1] "factor"
# $x3
# [1] "factor"

Но для простого просмотра вы можете использовать str :

str(a)
# 'data.frame':   100 obs. of  3 variables:
#  $ x1: num  -1.79 -1.091 1.307 1.142 -0.972 ...
#  $ x2: Factor w/ 2 levels "a","b": 2 1 1 1 2 1 1 1 1 2 ...
#  $ x3: Factor w/ 2 levels "a","b": 1 1 1 1 1 1 1 1 1 1 ...

Дополнительное объяснение согласно комментариям:

Почему lapply работает, а apply - нет?

Первое, что делает apply , - это преобразовывает аргумент в матрицу. Итак, apply (a) эквивалентно apply (as.matrix (a)) . Как видите, str (as.matrix (a)) дает вам:

chr [1:100, 1:3] " 0.075124364" "-1.608618269" "-1.487629526" ...
- attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:3] "x1" "x2" "x3"

Факторов больше нет, поэтому class возвращает "character" для все столбцы.
lapply работает со столбцами, поэтому дает вам то, что вы хотите (он делает что-то вроде класса ($ имя_столбца) для каждого столбца).

Вы можете увидеть в справке к применить , почему применяют и как.фактор не работает:

Во всех случаях результат приводится к одному из базовых векторных типов с помощью as.vector перед установкой размеров, {{1} } так, что (например) результаты множителя будут приведены к массиву символов.

Почему sapply и as.factor не работают, вы можете увидеть в справке по sapply :

Value (...) Атомарный вектор или матрица или список той же длины, что и X (...) Если происходит упрощение, тип выходных определяется из наивысшего типа возвращаемые значения в иерархии NULL

Вы никогда не получите матрицу факторов или data.frame.

Как преобразовать вывод в data.frame ?

Просто используйте as.data.frame , как вы писали в комментарии:

a2 <- as.data.frame(lapply(a, as.factor))
str(a2)
'data.frame':   100 obs. of  3 variables:
 $ x1: Factor w/ 100 levels "-2.49629293159922",..: 60 6 7 63 45 93 56 98 40 61 ...
 $ x2: Factor w/ 2 levels "a","b": 1 1 2 2 2 2 2 1 2 2 ...
 $ x3: Factor w/ 2 levels "a","b": 1 1 1 1 1 1 1 1 1 1 ...

Но если вы хотите заменить выбранные символьные столбцы с коэффициентом есть трюк:

a3 <- data.frame(x1=letters, x2=LETTERS, x3=LETTERS, stringsAsFactors=FALSE)
str(a3)
'data.frame':   26 obs. of  3 variables:
 $ x1: chr  "a" "b" "c" "d" ...
 $ x2: chr  "A" "B" "C" "D" ...
 $ x3: chr  "A" "B" "C" "D" ...

columns_to_change <- c("x1","x2")
a3[, columns_to_change] <- lapply(a3[, columns_to_change], as.factor)
str(a3)
'data.frame':   26 obs. of  3 variables:
 $ x1: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ x2: Factor w/ 26 levels "A","B","C","D",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ x3: chr  "A" "B" "C" "D" ...

Вы можете использовать его для замены всех столбцов, используя:

a3 <- data.frame(x1=letters, x2=LETTERS, x3=LETTERS, stringsAsFactors=FALSE)
a3[, ] <- lapply(a3, as.factor)
str(a3)
'data.frame':   26 obs. of  3 variables:
 $ x1: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ x2: Factor w/ 26 levels "A","B","C","D",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ x3: Factor w/ 26 levels "A","B","C","D",..: 1 2 3 4 5 6 7 8 9 10 ...
30
ответ дан 1 December 2019 в 20:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: