2015-12-17 2 views
3

Я потянул набор данных из базы данных PostgreSQL, чтобы работать с ним в R. Во время работы над этим я постоянно спотыкался, имея факторы в некоторых областях, которые мне не нужны в качестве факторов. Итак, я вернулся к коду, который я использовал для вывода данных, и обеспечил, чтобы был установлен options(stringsAsFactors = FALSE).Почему переменные строкиAsFactors в R изменяют размер файла?

Исходный файл .RData, хранящий извлеченные данные (пять таблиц плюс переменная, хранящая время, в течение которого данные были извлечены) составляла приблизительно 800 МБ. Обновленная версия, где строки не были сохранены в качестве факторов, превышала 2 ГБ. Ничто не изменилось в базе данных или внутри моего кода, за исключением того, что для параметра stringsAsFactors значение false.

Мое первоначальное подозрение заключалось в том, что уровни факторов были более эффективными для хранения текста, поскольку фактический текст будет храниться один раз в качестве уровня, а затем каждое значение будет просто присвоено уровню. Но я не думаю, что это правильно - я понимаю, что факторы в R : символьные данные со структурой сверху. Таким образом, в этом случае я не думаю, что значительная разница в размере файла.

Итак, мой вопрос: почему изменение stringsAsFactors от TRUE до FALSE изменило размер результирующих данных таким образом?

+4

короткий ответ: факторы являются целыми числами с дополнительным атрибутом (метки), в то время как вся строка символов должна храниться для каждой строки – rawr

+0

@rawr имеет смысл, но я никогда не думал об этом как о причине, почему 'stringsAsFactors' по умолчанию - «TRUE». благодаря! – MichaelChirico

+0

'factor's в R предназначены для этой цели: сохранить память при хранении длинных векторов строк, которые могут иметь небольшое количество различных значений. Ваше первоначальное подозрение было на месте. – nicola

ответ

1

Объединение комментариев с вопроса в ответ.

Нижняя строка впереди: R факторов - это числовые векторы с прикрепленными метками, и они используют операции с символами и сравнения. Это отличается от SAS, где категории создаются путем применения независимых факторов к числовым переменным и где используются числовые операции и сравнения.

В целом, мое первоначальное подозрение в отношении факторов, являющихся числовыми значениями, назначенными для установки текстовых строк, является правильным. Есть несколько различий между тем, как SAS и R справляются с этим, что явилось причиной моего вопроса.

Вкратце, SAS позволяет создавать и применять пользовательские форматы к числовым данным. Итак, если у вас есть категориальные данные, которые хранятся в числовой переменной (например, классифицируя расы в числовые категории), вы можете сохранить эту переменную цельной при отображении вывода с использованием символьных строк.

Рассмотрим пример SAS:

DATA sample; 
    INPUT id race; 
    DATALINES; 
    1 1 
    2 1 
    3 2 
    4 3 
    5 1 
    6 2 
    7 4 
    8 3 
    9 1 
    ; 
RUN; 

PROC FORMAT; 
    VALUE raceft 1 = 'White' 
       2 = 'Black' 
       3 = 'Asian' 
       4 = 'Other'; 
RUN; 

PROC PRINT DATA=sample; 
    FORMAT race raceft.; 
RUN; 

В этом выходы:

Obs id race 
1  1 White 
2  2 White 
3  3 Black 
4  4 Asian 
5  5 White 
6  6 Black 
7  7 Other 
8  8 Asian 
9  9 White 

Однако, в этом примере, переменная race остается числовым. Операции SAS против него используют числовые категории и операции сравнения. Например, выбор всех белых лиц будет выполнен с использованием операции race = 1.

Напротив, R сохранит эти данные в качестве фактора. Рассмотрим следующее.

sample <- data.frame(id = c(1:9), 
        race = c(1,1,2,3,1,2,4,3,1)) 
sample$race <- factor(x = sample$race, 
         levels = c(1:4), 
         labels = c("White","Black","Asian","Other")) 

> sample 
    id race 
1 1 White 
2 2 White 
3 3 Black 
4 4 Asian 
5 5 White 
6 6 Black 
7 7 Other 
8 8 Asian 
9 9 White 

В этом случае переменная race теперь класса factor и R использует символьные сравнения и операции против него. Например, выбор всех белых лиц в этом случае будет выполнен с использованием какой-либо операции race = "White".

Несмотря на то, что R использует операции символа против факторов, данные фактически не сохраняются как символьная переменная. Структура фактора:

> dput(sample$race) 
structure(c(1L, 1L, 2L, 3L, 1L, 2L, 4L, 3L, 1L), .Label = c("White","Black", "Asian", "Other"), class = "factor") 

Это согласуется с документацией для factor, который гласит:

factor возвращает объект класса "factor", который имеет множество целочисленных кодов длиной x с атрибутом "levels" режима character и уникальных (!anyDuplicated(.)) записей. Если аргумент ordered истинен (или используется ordered()), результат имеет класс c("ordered", "factor").

Таким образом, R действительно хранит факторы как числовые значения с прикрепленными метками. Это уменьшает объем памяти, необходимый для хранения многих записей, которые принимают небольшое количество дискретных значений. Однако, несмотря на то, что базовые значения являются числовыми, R использует символьные операторы при работе с факторами, а не с числовыми.

+0

Выглядит неплохо (не могу судить о части SAS). – Jaap

+0

Я действительно наткнулся на этот вопрос еще 2 дня назад и поставил его на свой список дел, чтобы добавить ответ CW. Итак, вы спасли мне какую-то работу ;-) – Jaap

Смежные вопросы