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: |

Individual messages can be fully encrypted. But the user has to turn on that function. It's not automatic, as it is on Signal and WhatsApp. "There are several million Russians who can lift their head up from propaganda and try to look for other sources, and I'd say that most look for it on Telegram," he said. He floated the idea of restricting the use of Telegram in Ukraine and Russia, a suggestion that was met with fierce opposition from users. Shortly after, Durov backed off the idea. The fake Zelenskiy account reached 20,000 followers on Telegram before it was shut down, a remedial action that experts say is all too rare. This provided opportunity to their linked entities to offload their shares at higher prices and make significant profits at the cost of unsuspecting retail investors.
from us


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