Telegram Group & Telegram Channel
История факторов в R

Сегодня разберем историю факторов в R, почему раньше при чтении таблиц аргумент stringsAsFactors по умолчанию был TRUE, и почему с версии R 4.0 это отменили, а также нужны ли факторы сейчас.

Моя история знакомства с факторами в R была такова: когда я только начинала осваивать R (это было в 2017 году), и использовала его для работы с табличками дифференциальной экспрессии генов, то мне сразу сказали, что при чтении таблицы надо использовать аргумент stringsAsFactors = FALSE, чтобы строки не превратились в факторы. Прозвучало это супер непонятно, но далее я обратила внимание, что если этого не делать, то после фильтрации таблицы в строковых переменных остаются какие-то уровни (levels), это было неудобно, поэтому я стала следить, чтобы всегда при чтении таблиц было указано stringsAsFactors = FALSE. И потом при работе уже с дисперсионным анализом поняла, зачем нужны были факторы, и как их использовать, но все равно они оставались чем-то загадочным, средним между строкой и числом, даже казались мне ближе к строке (но это не так, сейчас разберем почему).

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

Кроме этого, есть еще одна менее очевидная причина. Раньше хранение факторов занимало меньше места в памяти, чем хранение строк. Дело в том, что факторы во внутреннем представлении R – это integer, то есть целые числа, соответственно занимают около 4 байт памяти. При этом строки занимают больше памяти и при работе с категориальными переменными каждая строка таблицы занимала свое место в памяти (то есть если записано disease в 100 строках, то грубо говоря и памяти будет занято как место занимаемое строкой disease*100) [1].
Плюс сравнивать факторы было проще, чем строки, поскольку сравнение чисел происходит за фиксированное время, в то время как для сравнения строк необходимо было "проходить" каждую строку побайтно.


🖥 Все изменилось в обновлении R 2.6.0 в 2007 году, когда сделали хеширование CHARSXP, что означало, что теперь ВСЕ строки хешируются и хранятся в глобальном пуле строк, и теперь к строкам обращались по целочисленным указателям: не было нужды хранить каждую копию строки, достаточно было хранить только указатель.
Между прочим, это обновление было сделано благодаря проекту Bioconductor, потому что разработчикам приходилось работать с большими строками, например, с последовательностями нуклеиновых кислот и белков, и без хеширования строк работа со старым типом была максимально неэффективной.

После этого выигрыш в хранении и сравнении строк в виде факторов перестал быть существенным, тем не менее факторы все еще необходимы в lm, glm и других подобных функциях, а также для упорядочивания категорий на графике.

Иллюстрация объема памяти, занимаемого на хранение строк (пример взят из книги Advanced R):
banana <- "bananas bananas bananas"
obj_size(banana)
#> 136 B
obj_size(rep(banana, 100))
#> 928 B

Мы создали 100 копий строки, но при этом занимаемый объем увеличился всего в 6.8 раз!

При чтении таблиц средствами базового R аргумент stringsAsFactors был TRUE, и только в 2020 году с версии R 4.0 разработчики R это изменили на FALSE. Только в функциях из пакета readr строки не превращались в факторы по умолчанию. На мой взгляд, разработчики R довольно поздно изменили дефолтное поведение функций read.table и read.csv, но лучше уж поздно чем никогда, хотя я сейчас пользуюсь только readr-ом для загрузки таблиц (и fread, при необходимости).

Ссылки на источники:
1. https://simplystatistics.org/posts/2015-07-24-stringsasfactors-an-unauthorized-biography/
2. https://notstatschat.rbind.io/2015/07/25/stringsasfactors-sigh/
3. https://notstatschat.rbind.io/2022/03/31/stringsasfactors-do-you-feel-lucky/

#R #history #baseR
Please open Telegram to view this post
VIEW IN TELEGRAM



group-telegram.com/stats_for_science/84
Create:
Last Update:

История факторов в R

Сегодня разберем историю факторов в R, почему раньше при чтении таблиц аргумент stringsAsFactors по умолчанию был TRUE, и почему с версии R 4.0 это отменили, а также нужны ли факторы сейчас.

Моя история знакомства с факторами в R была такова: когда я только начинала осваивать R (это было в 2017 году), и использовала его для работы с табличками дифференциальной экспрессии генов, то мне сразу сказали, что при чтении таблицы надо использовать аргумент stringsAsFactors = FALSE, чтобы строки не превратились в факторы. Прозвучало это супер непонятно, но далее я обратила внимание, что если этого не делать, то после фильтрации таблицы в строковых переменных остаются какие-то уровни (levels), это было неудобно, поэтому я стала следить, чтобы всегда при чтении таблиц было указано stringsAsFactors = FALSE. И потом при работе уже с дисперсионным анализом поняла, зачем нужны были факторы, и как их использовать, но все равно они оставались чем-то загадочным, средним между строкой и числом, даже казались мне ближе к строке (но это не так, сейчас разберем почему).

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

Кроме этого, есть еще одна менее очевидная причина. Раньше хранение факторов занимало меньше места в памяти, чем хранение строк. Дело в том, что факторы во внутреннем представлении R – это integer, то есть целые числа, соответственно занимают около 4 байт памяти. При этом строки занимают больше памяти и при работе с категориальными переменными каждая строка таблицы занимала свое место в памяти (то есть если записано disease в 100 строках, то грубо говоря и памяти будет занято как место занимаемое строкой disease*100) [1].
Плюс сравнивать факторы было проще, чем строки, поскольку сравнение чисел происходит за фиксированное время, в то время как для сравнения строк необходимо было "проходить" каждую строку побайтно.


🖥 Все изменилось в обновлении R 2.6.0 в 2007 году, когда сделали хеширование CHARSXP, что означало, что теперь ВСЕ строки хешируются и хранятся в глобальном пуле строк, и теперь к строкам обращались по целочисленным указателям: не было нужды хранить каждую копию строки, достаточно было хранить только указатель.
Между прочим, это обновление было сделано благодаря проекту Bioconductor, потому что разработчикам приходилось работать с большими строками, например, с последовательностями нуклеиновых кислот и белков, и без хеширования строк работа со старым типом была максимально неэффективной.

После этого выигрыш в хранении и сравнении строк в виде факторов перестал быть существенным, тем не менее факторы все еще необходимы в lm, glm и других подобных функциях, а также для упорядочивания категорий на графике.

Иллюстрация объема памяти, занимаемого на хранение строк (пример взят из книги Advanced R):

banana <- "bananas bananas bananas"
obj_size(banana)
#> 136 B
obj_size(rep(banana, 100))
#> 928 B

Мы создали 100 копий строки, но при этом занимаемый объем увеличился всего в 6.8 раз!

При чтении таблиц средствами базового R аргумент stringsAsFactors был TRUE, и только в 2020 году с версии R 4.0 разработчики R это изменили на FALSE. Только в функциях из пакета readr строки не превращались в факторы по умолчанию. На мой взгляд, разработчики R довольно поздно изменили дефолтное поведение функций read.table и read.csv, но лучше уж поздно чем никогда, хотя я сейчас пользуюсь только readr-ом для загрузки таблиц (и fread, при необходимости).

Ссылки на источники:
1. https://simplystatistics.org/posts/2015-07-24-stringsasfactors-an-unauthorized-biography/
2. https://notstatschat.rbind.io/2015/07/25/stringsasfactors-sigh/
3. https://notstatschat.rbind.io/2022/03/31/stringsasfactors-do-you-feel-lucky/

#R #history #baseR

BY Статистика и R в науке и аналитике


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/stats_for_science/84

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

I want a secure messaging app, should I use Telegram? These entities are reportedly operating nine Telegram channels with more than five million subscribers to whom they were making recommendations on selected listed scrips. Such recommendations induced the investors to deal in the said scrips, thereby creating artificial volume and price rise. On February 27th, Durov posted that Channels were becoming a source of unverified information and that the company lacks the ability to check on their veracity. He urged users to be mistrustful of the things shared on Channels, and initially threatened to block the feature in the countries involved for the length of the war, saying that he didn’t want Telegram to be used to aggravate conflict or incite ethnic hatred. He did, however, walk back this plan when it became clear that they had also become a vital communications tool for Ukrainian officials and citizens to help coordinate their resistance and evacuations. 'Wild West' In December 2021, Sebi officials had conducted a search and seizure operation at the premises of certain persons carrying out similar manipulative activities through Telegram channels.
from de


Telegram Статистика и R в науке и аналитике
FROM American