Почему str() показывает неверную информацию для уровней факторов после создания подматрицы в R?

#r #dataframe

#r #фрейм данных

Вопрос:

У меня есть следующий фрейм данных в R с 274569 строками и 15 столбцами:

 > str(x2)
'data.frame':   274569 obs. of  15 variables:
 $ ykod : int  99 99 99 99 99 99 99 99 99 99 ...
 $ yad  : Factor w/ 43 levels "BAKUGAN","BARBIE",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ per  : Factor w/ 3 levels "2 AYLIK","3 AYLIK",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ donem: int  201106 201106 201106 201106 201106 201106 201106 201106 201106 201106 ...
 $ sayi : int  201106 201106 201106 201106 201106 201106 201106 201106 201106 201106 ...
 $ mkod : int  359 361 362 363 366 847 849 850 1505 1506 ...
 $ mad  : Factor w/ 11045 levels "    Hilal Gida           ",..: 5163 3833 10840 8284 10839 2633 10758 10293 6986 6984 ...
 $ mtip : Factor w/ 30 levels "Abone Bürosu                                      ",..: 20 20 20 20 20 2 2 2 11 11 ...
 $ kanal: Factor w/ 2 levels "OB","SS": 2 2 2 2 2 2 2 2 1 1 ...
 $ bkod : int  110006 110006 110006 110006 110006 110006 110006 110006 110006 110006 ...
 $ bad  : Factor w/ 213 levels "4. Levent","500 Evler",..: 25 25 25 25 25 25 25 25 25 25 ...
 $ bolge: Factor w/ 12 levels "Adana Şehiriçi",..: 7 7 7 7 7 7 7 7 7 7 ...
 $ sevk : int  5 2 2 2 10 0 4 3 13 32 ...
 $ iade : int  0 2 1 2 4 0 3 2 0 8 ...
 $ satis: int  5 0 1 0 6 0 1 1 13 24 ...
  

Я создаю подматрицу и отображаю ее структуру:

 > msub <- x2[x2$ykod == 99,]
> str(msub)
'data.frame':   14367 obs. of  15 variables:
 $ ykod : int  99 99 99 99 99 99 99 99 99 99 ...
 $ yad  : Factor w/ 43 levels "BAKUGAN","BARBIE",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ per  : Factor w/ 3 levels "2 AYLIK","3 AYLIK",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ donem: int  201106 201106 201106 201106 201106 201106 201106 201106 201106 201106 ...
 $ sayi : int  201106 201106 201106 201106 201106 201106 201106 201106 201106 201106 ...
 $ mkod : int  359 361 362 363 366 847 849 850 1505 1506 ...
 $ mad  : Factor w/ 11045 levels "    Hilal Gida           ",..: 5163 3833 10840 8284 10839 2633 10758 10293 6986 6984 ...
 $ mtip : Factor w/ 30 levels "Abone Bürosu                                      ",..: 20 20 20 20 20 2 2 2 11 11 ...
 $ kanal: Factor w/ 2 levels "OB","SS": 2 2 2 2 2 2 2 2 1 1 ...
 $ bkod : int  110006 110006 110006 110006 110006 110006 110006 110006 110006 110006 ...
 $ bad  : Factor w/ 213 levels "4. Levent","500 Evler",..: 25 25 25 25 25 25 25 25 25 25 ...
 $ bolge: Factor w/ 12 levels "Adana Şehiriçi",..: 7 7 7 7 7 7 7 7 7 7 ...
 $ sevk : int  5 2 2 2 10 0 4 3 13 32 ...
 $ iade : int  0 2 1 2 4 0 3 2 0 8 ...
 $ satis: int  5 0 1 0 6 0 1 1 13 24 ...
  

Теперь у меня есть подматрица с 14367 строками и 15 столбцами, но уровни факторов все еще существуют. Они должны были быть уменьшены. Например, для yad , должен быть только один фактор.

Как я могу легко заставить str() показывать правильную информацию для уровней факторов, чтобы при вводе str(msub) она выдавала правильные значения?

Комментарии:

1. Как показывают ответы, str на самом деле дает вам правильную информацию. Однако работа с факторами в data.frames часто сбивает с толку. Рассмотрите возможность использования stringsAsFactors=FALSE в вашем исходном вызове read.table или read.csv для импорта данных.

Ответ №1:

Это ожидаемое поведение. Уровни факторов, которые не представлены в вашем подмножестве, не «исчезают», пока вы не сообщите им об этом. С недавнего времени вы можете использовать droplevels() .

Комментарии:

1. 1 Два других упомянули использование factor() в качестве решения — что действительно так droplevels.factor() и реализовано. Метод фрейма данных немного сложнее.

Ответ №2:

Фактически str показывает вам правильную структурную информацию: фактор может отображать уровни. Представьте себе объединение двух ваших подматриц, где одна содержит некоторые уровни, а другая — другой набор: объединить это было бы довольно сложно! Это просто то, как факторы работают в R.

Если вы хотите знать, какие факторы «присутствуют» в ваших данных, один из вариантов — использовать table для подсчета вхождений.

Если вы хотите, чтобы ваш фактор был уменьшен, чтобы он содержал только те уровни, которые действительно присутствуют, вы можете повторно применить к нему фактор:

 myfact<-factor(rep(1:2,5), levels=1:3, labels=letters[1:3])
myfact
# [1] a b a b a b a b a b
#Levels: a b c
factor(myfact)
# [1] a b a b a b a b a b
#Levels: a b
  

Вы можете просто применить это ко всем столбцам факторов вашего data.frame, чтобы получить то, что, по вашим словам, вы хотите.

Ответ №3:

Уровни фактора являются частью столбца и не зависят от фактически присутствующих уровней:

 > x <- factor(LETTERS[1:10])
> x
 [1] A B C D E F G H I J
Levels: A B C D E F G H I J
> y <- x[1]
> y
[1] A
Levels: A B C D E F G H I J
> factor(y)
[1] A
Levels: A
> 
  

Я уверен, что есть другой способ, но это должно сработать.

Ответ №4:

 x <- factor(LETTERS[1:10])
y <- x[1, drop=TRUE]
y