Text
                    
Никита Ткаченко Основы анализа данных на языке R
Nikita Tkachenko Data Insight Foundations Step-by-Step Data Analysis with R
Никита Ткаченко Основы анализа данных на языке R Пошаговый разбор методов Москва, 2025
УДК 004.6:004.438R ББК 16.35+32.973.2 Т48 Т48 Ткаченко Н. Основы анализа данных на языке R / пер. с англ. А. В. Логунова. – М.: ДМК Пресс, 2025. – 270 с.: ил. ISBN 978-5-93700-405-5 Назначение данной книги – устранить пробел между механическими навыками использования инструментов анализа и настоящим пониманием того, как работают эти инструменты и почему они применяются на практике. Эти знания обычно выходят за рамки стандартного процесса обучения анализу данных. Главы намеренно сделаны краткими, а материал излагается строго по существу и сопровождается иллюстрациями и примерами кода на языке R, но обязательное знание именно этого языка для работы с книгой не требуется. Издание будет полезно как профессиональным аналитикам данных для закрепления знаний, так и специалистам гуманитарного профиля, желающим приобрести навыки эффективного анализа и презентации данных в своей работе. УДК 004.6:004.438R ББК 16.35+32.973.2 First published in English under the title Data Insight Foundations, by Nikita Tkachenko, 1st edition. Copyright © Nikita Tkachenko 2025. This edition has been translated and published under licence from APress Media, LLC. APress Media, LLC takes no responsibility and shall not be made liable for the accuracy of the translation. Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. ISBN 979-8-8688-0579-0 (англ.) ISBN 978-5-93700-405-5 (рус.) © 2025 by Nikita Tkachenko © Перевод, оформление, издание, ДМК Пресс, 2025
Посвящаю эту книгу своему покойному дедушке Владимиру Замашикову
Содержание Об авторе...................................................................................................................13 О техническом рецензенте..................................................................................14 Признательности.....................................................................................................15 От издательства.......................................................................................................17 Введение....................................................................................................................18 Установка языка R и среды RStudio.................................................................20 Скачивание и установка языка R. ............................................................................20 Скачивание и установка среды RStudio. .................................................................21 Конфигурирование среды RStudio...........................................................................21 Установка пакетов. .....................................................................................................21 Часть I. РАБОТА С ДАННЫМИ .........................................................................23 Глава 1. Манипулирование данными...............................................................24 1.1. Основы...................................................................................................................24 1.1.1. Типы данных.................................................................................................26 1.2. Скачивание данных.............................................................................................28 1.2.1. Пример данных.............................................................................................28 1.3. Простейшие методы управления данными с помощью подпакета dplyr. ....30 1.3.1. Функция select()............................................................................................30 1.3.2. Функция filter()..............................................................................................31 1.3.3. Функция arrange().........................................................................................32 1.3.4. Функция mutate()..........................................................................................33 1.3.5. Функция case_match(). .................................................................................34 1.3.6. Функция summarize()...................................................................................34 1.3.7. Функция group_by().......................................................................................34 1.3.8. Функция ungroup(). ......................................................................................35 1.3.9. Аргумент .by. .................................................................................................36 1.3.10. Функция rowwise()......................................................................................37 1.3.11. Функция count()..........................................................................................38 1.3.12. Функция rename().......................................................................................38 1.3.13. Функция row_number()...............................................................................39 1.3.14. Функция skim()............................................................................................39 1.4. Обследование даты и времени с помощью подпакета lubridate..................40
Содержание  7 1.4.1. Функции ymd(), md(), hms(), ymd_hms(). ...................................................40 1.4.2. Функции year(), month(), day(). ...................................................................41 1.5. Краткий итог.........................................................................................................41 Глава 2. Упорядоченные данные.......................................................................42 2.1. Пример. .................................................................................................................44 2.2. Подпакет tidyr.......................................................................................................45 2.2.1. Функция pivot_longer().................................................................................45 2.2.2. Функция pivot_wider()..................................................................................46 2.2.3. Функции separate() и unite()........................................................................47 2.3. Функции tibble() и tribble().................................................................................49 2.4. Пакет janitor: очистка данных. ..........................................................................50 2.4.1. Функция clean_names()................................................................................50 2.4.2. Функция remove_empty().............................................................................51 2.4.3. Функция remove_constant().........................................................................51 2.4.4. Функции convert_to_date() и convert_to_datetime()..................................52 2.4.5. Функция row_to_names()..............................................................................52 2.5. Краткий итог.........................................................................................................53 Глава 3. Реляционные данные............................................................................54 3.1. Типы отношений..................................................................................................54 3.1.1. Отношение «один к одному» (1:1). ............................................................54 3.1.2. Отношение «один ко многим» (1:M). ........................................................55 3.1.3. Отношение «многие ко многим» (M:N). ...................................................55 3.2. Понятие ключей...................................................................................................56 3.3. Типы соединений.................................................................................................56 3.3.1. Внешние соединения...................................................................................57 3.3.2. Фильтрация соединений.............................................................................60 3.4. Визуализация отношений. .................................................................................61 3.5. Краткий итог.........................................................................................................63 Глава 4. Валидация данных.................................................................................64 4.1. Инспекция данных вручную..............................................................................64 4.2. Улаживание проблем с данными.......................................................................65 4.2.1. Подтверждение истинности своих условий.............................................65 4.2.2. Точная валидация с помощью пакета pointblank....................................67 4.3. Краткий итог.........................................................................................................69 Глава 5. Восполнение пропущенных данных...............................................70 5.1. Типы пропущенных данных. .............................................................................70 5.2. Работа с пропущенными данными...................................................................71 5.2.1. Явная обработка пропущенных данных с помощью функции complete().................................................................................................................72 5.2.2. Простые методы восполнения. ..................................................................74 5.2.3. Наилучший сценарий из наихудших и наихудший сценарий из наилучших..........................................................................................................79
8  Содержание 5.2.4. Множественные восполнения....................................................................80 5.3. Краткий итог.........................................................................................................83 5.3.1. Таблица методов восполнения пропущенных данных. .........................84 Часть II. ВОСПРОИЗВОДИМЫЕ НАУ ЧНЫЕ ИЗЫСКАНИЯ . ...............86 Глава 6. Воспроизводимое исследование......................................................87 6.1. Грамотное программирование..........................................................................88 6.2. Краткий итог.........................................................................................................90 Глава 7. Воспроизводимая среда.......................................................................91 7.1. Пакет renv..............................................................................................................92 7.1.1. Рабочий поток...............................................................................................92 7.2. Вычислительные среды.......................................................................................93 7.3. Краткий итог.........................................................................................................94 Глава 8. Введение в командную оболочку.....................................................95 8.1. Освоение основных команд...............................................................................95 8.2. Начало работы с Nano. ........................................................................................96 Глава 9. Контроль версий с помощью Git и GitHub.....................................98 9.1. Система контроля версий Git и веб-платформа GitHub. ...............................99 9.2. Основы.................................................................................................................100 9.3. Руководство по использованию файла .gitignore. ........................................102 9.3.1. Перечисление файлов, которые следует игнорировать........................103 9.3.2. Файл .gitignore в других программах. .....................................................104 9.4. Краткий итог.......................................................................................................104 Глава 10. Стилизация и статический анализ исходного кода................105 10.1. Руководство tidyverse по стилю.....................................................................106 10.1.1. Пробелы и отступы...................................................................................106 10.1.2. Правила именования...............................................................................106 10.1.3. Фигурные скобки......................................................................................107 10.1.4. Комментарии. ...........................................................................................107 10.1.5. Длинные функции....................................................................................108 10.2. Форматировщик...............................................................................................109 10.3. Статический анализатор исходного кода. ...................................................109 10.4. Краткий итог.....................................................................................................110 Глава 11. Модульный исходный код..............................................................111 11.1. Реиспользование функций.............................................................................111 11.2. Разбивка исходного кода................................................................................112 1.3. Упаковка исходного кода в модули.................................................................114 11.4. Краткий итог.....................................................................................................115
Содержание  9 Часть III. ОБЗОР НАУ ЧНЫХ ПУБЛИКАЦИЙ И НАПИСАНИЕ СТАТЬИ ....................................................................................................................116 Глава 12. Обзор научных публикаций...........................................................117 12.1. Поиск. ................................................................................................................117 12.2. Управление справочными материалами. ....................................................118 12.3. Чтение статей...................................................................................................119 12.4. Ведение заметок. .............................................................................................120 12.5. Краткий итог.....................................................................................................121 Глава 13. Написание научной статьи..............................................................122 13.1. WYSIWYG...........................................................................................................122 13.2. Языки разметки. ..............................................................................................123 13.2.1. HTML...........................................................................................................123 13.2.2. LaTeX...........................................................................................................123 13.2.3. Упрощенная разметка Markdown...........................................................124 13.2.4. YAML...........................................................................................................124 13.2.5. Pandoc.........................................................................................................125 13.3. Quarto.................................................................................................................125 13.3.1. Ваш первый документ. ............................................................................126 13.4. Краткий итог.....................................................................................................129 Глава 14. Макетирование и ссылки на справочные материалы..........130 14.1. Пакет knitr.........................................................................................................130 14.2. Блоки div............................................................................................................131 14.3. Диаграммы........................................................................................................132 14.4. Цитирование. ...................................................................................................133 14.5. Краткий итог.....................................................................................................134 Глава 15. Совместная работа и шаблонное форматирование документов..............................................................................................................135 15.1. Оптимизация совместной работы с помощью инструмента trackdown....................................................................................................................135 15.2. Шаблонное форматирование документов...................................................137 15.3. Краткий итог.....................................................................................................138 Часть IV. СБОР ДАННЫХ . .................................................................................139 Глава 16. Суммарная ошибка опроса.............................................................140 16.1. Репрезентативность – люди, которых вы спрашиваете.............................143 16.1.1. Взятие выборок.........................................................................................145 16.1.2. От чего зависят ответы............................................................................146 16.2. Разработка вопросов.......................................................................................148 16.2.1. Ответы на вопросы...................................................................................148 16.2.2. Рекомендации по эффективной разработке вопросов.......................150
10  Содержание 16.2.3. Влияние порядка следования вопросов................................................150 16.2.4. В опросе говорится: «Бекон»!. ................................................................151 16.2.5. Типы вопросов..........................................................................................152 16.2.6. Шкалы Лайкерта. ......................................................................................153 16.2.7. Варианты «не знаю» и «затрудняюсь ответить». .................................154 16.2.8. Продолжительность опроса. ...................................................................155 16.2.9. Приглашение к опросу.............................................................................156 16.2.10. Итеративное составление вопросов....................................................157 16.3. Инструменты проведения опросов...............................................................157 16.3.1. Методы проведения физических опросов............................................157 16.3.2. Платформы для проведения цифровых опросов. ...............................158 16.3.3. Платформы для рекрутирования участников......................................159 16.4. Краткий итог.....................................................................................................160 Глава 17. Документирование. ...........................................................................161 17.1. Принципы документирования.......................................................................161 17.1.1. Иерархическая структура документации..............................................163 17.2. Физическая и электронная документация...................................................165 17.3. Организация данных в электронных таблицах...........................................166 17.3.1. Организация электронных таблиц.........................................................167 17.3.2. Ввод данных...............................................................................................168 17.4. Администрирование........................................................................................170 17.5. Финансовая отчетность в научных исследованиях. ...................................171 17.6. Коммуникация..................................................................................................173 17.7. Краткий итог. ....................................................................................................173 Глава 18. Интерфейсы прикладного программирования. .....................175 18.1. Основы API........................................................................................................175 18.2. Использование API на языке R. .....................................................................178 18.3. API системы Qualtrics......................................................................................180 18.4. Интеграция служб Google со средой языка R...............................................182 18.5. API OpenAI. .......................................................................................................184 18.6. Краткий итог.....................................................................................................186 Часть V. ПРЕЗЕНТАЦИЯ ДАННЫХ . .............................................................187 Глава 19. Основы визуализации данных......................................................188 19.1. Восприятие. ......................................................................................................188 19.1.1. Предвнимательная обработка................................................................189 19.2. Визуальное кодирование................................................................................196 19.2.1. Оценивание графиков. ............................................................................197 19.3. Краткий итог.....................................................................................................199 Глава 20. Визуализация данных......................................................................200 20.1. Разведывательный и объяснительный типы...............................................200
Содержание  11 20.2. Грамматика графики.......................................................................................202 20.2.1. Графические интерфейсы для пакета ggplot2......................................208 20.3. Интерактивные графики. ...............................................................................210 20.3.1. HTML-виджеты. ........................................................................................211 20.4. Краткий итог.....................................................................................................213 Глава 22. Подходящий график для работы.................................................214 21.1. Сравнение категорий......................................................................................214 21.1.1. Леденцовый график.................................................................................215 21.1.2. Пулевой график. .......................................................................................215 21.2. Распределение..................................................................................................216 21.2.1. График плотности.....................................................................................217 21.2.2. Многоугольник частот.............................................................................218 21.2.3. Коробчатый график..................................................................................219 21.2.4. Скрипичный график. ...............................................................................219 21.2.5. Ульевый график. .......................................................................................220 21.2.6. График дождевых облаков.......................................................................221 21.2.7. Графики по краям.....................................................................................222 21.3. Пропорции........................................................................................................223 21.3.1. Многослойный столбчатый график.......................................................223 21.3.2. Круговой график.......................................................................................224 21.3.3. Вафельный график...................................................................................226 21.3.4. Древовидные карты.................................................................................226 21.4. Корреляция.......................................................................................................227 21.4.1. Диаграмма рассеяния. .............................................................................227 21.4.2. Коррелограммы. .......................................................................................227 21.5. Изменение во временной динамике. ...........................................................229 21.5.1. Линейный график.....................................................................................229 21.5.2. Водопадный график.................................................................................229 21.6. Краткий итог.....................................................................................................230 Глава 22. Цветовые данные. .............................................................................231 22.1. Какие цвета выбирать.....................................................................................231 22.1.1. Взаимодополняющая гармония с положительной/отрицательной коннотацией..............................................232 22.1.2. Почти взаимодополняющая гармония для выделения двух рядов, один из которых находится в центре внимания.................................233 22.1.3. Аналогичная/триадическая гармония для выделения трех рядов.....234 22.1.4. Выделение одного ряда на фоне двух соотнесенных рядов..............235 22.1.5. Схема на основе аналогичной взаимодополняющей гармонии для одного главного ряда и трех вторичных ему рядов.................................236 22.1.6. Схема на основе двойной взаимодополняющей гармонии для двух пар, одна из которых является доминирующей..............................237 22.1.7. Прямоугольная или квадратная схема на основе взаимодополняющей гармонии для четырех рядов с одинаковым акцентом................................................................................................................237
12  Содержание 22.1.8. Схема последовательных цветов. ..........................................................238 22.1.9. Схемы с расходящимися цветами..........................................................239 22.1.10. Предварительно созданные шкалы.....................................................239 22.2. Цветовые системы...........................................................................................240 22.2.1. Внимание: цветовые карты могут увеличивать риск смерти!..........244 22.2.2. Итак, что же следует использовать?. .....................................................245 22.3. Краткий итог.....................................................................................................246 Глава 23. Создание таблиц.................................................................................247 23.1. Таблицы gt.........................................................................................................247 23.1.1. Подготовка данных. .................................................................................248 23.2. Таблицы DT.......................................................................................................255 23.3. Краткий итог.....................................................................................................257 Эпилог. ......................................................................................................................258 Справочные материалы. ....................................................................................259 Предметный указатель. ......................................................................................263
Об авторе Никита Ткаченко возглавляет консалтинговое агентство Evalyn, специализирующееся на аудите обслуживания клиентов на основе искусственного интеллекта (ИИ) и технологических решениях по анализу данных. Он помогает организациям любого размера использовать ИИ и данные, чтобы оптимизировать процессы принятия решений, систематизировать операции и улучшать качество обслуживания покупателей. Обладая солидным опытом в области изысканий и аналитики, Никита также преподает курсы по инструментам исследования, руководит студентами и проводит академические исследования в Университете Сан-Франциско.
О техническом рецензенте Сиджо Валаяккад Маникандан – опытный специа­ лист в области искусственного интеллекта и науки о данных. Обладает обширным опытом управления крупномасштабными проектами в области науки о данных для корпораций из списка Fortune 500. Сиджо получил степень магистра наук в области деловой аналитики в знаменитом Техасском университете в Остине и степень бакалавра инженерных наук в Институте технологии и науки Бирлы в Пилани, Индия. Для достижения исключительных результатов он сочетает свои академические знания и практический опыт. Сиджо внес значительный вклад в развитие науки о данных и научных исследований благодаря не только своим профессиональным и академическим достижениям, но и своей преданности сообществу. Он входит в состав нескольких авторитетных организаций, таких как Американская статистическая ассоциация, проводит независимые исследования, а также активно рецензирует научные и профессиональные монографии, был наставником молодых исследователей данных и руководил молодыми стартапами. Более того, его опыт позволил ему войти в состав жюри нескольких престижных премий, включая Webby Awards. Будучи целеустремленным исследователем и идейным лидером, Сиджо продолжает оказывать глубокое влияние на сферу науки о данных, вдохновляя новое поколение исследователей данных. Его вклад продвинул междисциплинарную область науки о данных и научных исследований вперед и помог определить будущее этой быстро развивающейся отрасли, что сделало его бесценным активом для сообщества и провидцем в своей сфере.
Признательности Посвящаю эту книгу своему покойному дедушке Владимиру Замашикову. Выражаю свою глубочайшую благодарность Томасу Вайнанди, который убедил меня превратить черновой вариант в опубликованную книгу и направлял меня на протяжении всего процесса. Без него эта книга была бы невозможна. Я глубоко признателен Парсу Рахими за его неизменную поддержку, тщательный анализ всех моих глав, правок и идей, а также за предоставленные художественные работы с элементами фантастики. Также выражаю благодарность Алессандре Кассар и Майклу Джонасу за их поддержку на протяжении всего моего академического пути. Особая благодарность Питеру Лоренцену, Керу Гиббсу и Джесси Анттила-Хьюзу за их неоценимое наставничество и поддержку. Я признателен Шивани Шукле, Брюсу Вайдику, Мише Цыгману, Марио Лиму, Стиву Треттелу, Мехмету Эмре, Эндрю Хоббсу, Арману Хачияну, Робизону Хубулашвили и Конраду Пошу за рецензирование глав и предоставленную поддержку. Кроме того, я благодарен преподавательскому составу, библиотекарям, сотрудникам писательского центра и Центра деловых исследований и инноваций (CBSI) Университета Сан-Франциско за их наставничество. Гордон Гетти заслуживает благодарности за то, что вдохновил меня более уверенно писать о своих навыках. В процессе публикации мне помогал коллектив издательства APress, в особенности Шауль Элсон, редактор-заказчик, Лаура Берендсон, редактор-разработчик, и Гриффин Винклер, ассистент редактора. Мой технический рецензент Сиджо Маникандан предоставил комментарии, которые значительно обогатили книгу дополнительными примерами и пояснениями. Выражаю особую благодарность всем сотрудникам издательства APress, благодаря чьим усилиям эта книга стала реальностью. Выражаю глубокую признательность Джону Четвинду, Джейку Консгроуву, Тимофею Лопухову и Александру Рому за их поддержку, любопытство и доверие к моей работе. Должен поблагодарить свою семью, включая мою маму Екатерину Ткаченко, чья вера в меня вдохновила меня на запуск этого проекта, моего отца Антона Ткаченко, приемную мать Дарью Ткаченко, а также бабушку и дедушку Валентину и Александра Ткаченко и Раису Замашикову. Особая благодарность Анастасии Терновской за ее непоколебимую веру в меня. Я очень признателен Марии Аксутенко за создание иллюстрации «кошкаисследователь».
16  Признательности Особая благодарность также коллективу Posit за их неоценимый вклад и поддержку сообщества. Наконец, выражаю искреннюю признательность сообществу разработчиков открытого исходного кода и всем тем, кто щедро делился своими знания­ ми в интернете. Вы сделали это реальным, и я рад возможности принять участие в обсуждении. Надеюсь, что эта книга окажется полезной на вашем пути к овладению методами научных изысканий.
От издательства Отзывы и пожелания Мы всегда рады отзывам наших читателей. Расскажите нам, что вы ду­маете об этой книге – что понравилось или, может быть, не понравилось. Отзывы важны для нас, чтобы выпускать книги, которые будут для вас максимально полезны. Вы можете написать отзыв на нашем сайте www.dmkpress.com, зайдя на страницу книги и оставив комментарий в разделе «Отзывы и рецензии». Также можно послать письмо главному редактору по адресу dmkpress@gmail. com; при этом укажите название книги в теме письма. Если вы являетесь экспертом в какой-либо области и заинтересованы в написании новой книги, заполните форму на нашем сайте по адресу http:// dmkpress.com/authors/publish_book/ или напишите в издательство по адресу dmkpress@gmail.com. Список опечаток Хотя мы приняли все возможные меры для того, чтобы обеспечить высокое качество наших текстов, ошибки все равно случаются. Если вы найдете ошибку в одной из наших книг, мы будем очень благодарны, если вы сообщите о ней главному редактору по адресу dmkpress@gmail.com. Сделав это, вы избавите других читателей от недопонимания и поможете нам улучшить последующие издания этой книги. Нарушение авторских прав Пиратство в интернете по-прежнему остается насущной проблемой. Издательство «ДМК Пресс» очень серьезно относится к вопросам защиты авторских прав и лицензирования. Если вы столкнетесь в интернете с незаконной публикацией какой-либо из наших книг, пожалуйста, пришлите нам ссылку на интернет-ресурс, чтобы мы могли применить санкции. Ссылку на подозрительные материалы можно прислать по адресу элект­ ронной почты dmkpress@gmail.com. Мы высоко ценим любую помощь по защите наших авторов, благодаря которой мы можем предоставлять вам качественные материалы.
Введение Эта книга родилась из моих разочарований и опыта в сфере высшего образования и профессиональной деятельности. Она была написана на основе заметок и материалов весеннего курса 2023 года по разработке опросов под влиянием восторженных откликов и содержательных вопросов моих студентов. Молодые специалисты в области исследования данных, как правило, на своих занятиях знакомятся с моделями, экспериментами и теориями и часто возвращаются к этим знаниям позже. Однако для проведения высокока­ чественных изысканий и анализа требуется более глубокое понимание инструментов и того, «как» это делается, а не только того, «что» делается и «почему». Эти знания часто выходят за пределы того, чему учат в рамках стандартной учебной программы. В данной книге я стремлюсь преодолеть этот пробел, помогая вам перейти от знания того, что вы хотите делать, к пониманию того, как это делать. В свои главы я вложил сотни часов разочарования, так что вам не придется проходить этот путь самостоятельно. Эта книга не является исчерпывающим руководством; если вы ищете именно его, то, возможно, вам лучше поискать в другом месте. Данная же книга может служить картой, очерчивающей необходимые инструменты и темы для вашего исследовательского путешествия. Ее цель состоит в том, чтобы развить вашу интуицию и подсказать места, где найти более подробную информацию. Главы намеренно сделаны краткими, а материал излагается по существу. Они призваны раскрывать и просвещать, а не утомлять. Вы узнаете об эффективном управлении данными, проведении воспроизводимых исследований, составлении обзора научных публикаций и методах написания текстов, а также об эффективной визуализации данных. Эта книга, изначально написанная под впечатлением от моего обучения в аспирантуре по экономике, представляет ценность для всех дисциплин. В ней содержатся важные сведения для всех, кто работается с данными, от гуманитарных наук до анализа данных и естественных наук. Независимо от того, оттачиваете ли вы свой опыт в области анализа данных или являетесь в ней новичком, настоящая книга обещает предложить вам нечто ценное. Приведенные в книге примеры в основном написаны на языке R, что предполагает базовое понимание языка, но это не обязательно. Некоторые главы, в особенности те, которые посвящены теории, вообще не требуют знаний
Введение  19 в области программирования. Материал оказался полезен широкому кругу читателей, включая веб-разработчиков, математиков, аналитиков данных и экономистов. Книга организована таким образом, чтобы быть всеохватывающей и давать информацию независимо от вашего уровня владения программированием или профессиональной подготовки. Ее структура позволяет выбирать гибкие пути чтения; можно просматривать главы последовательно, чтобы усваивать материал систематически либо переходить непосредственно к наиболее актуальным для вас темам.
Установка языка R и среды RStudio Добро пожаловать в захватывающий мир анализа данных на языке R, мас­ терски выполненного специально для статистического анализа и визуализации данных. Удобный синтаксис и воспроизводимость данного языка делают его идеальным выбором как для новичков, так и для профессионалов. Однако прежде чем приступить к разведывательному анализу данных и моделированию, важно провести различие между языком программирования R и интегрированной средой разработки (IDE) RStudio, которая расширяет функциональные средства языка R. Скачивание и установка языка R Язык R поддерживается и распространяется через всеобъемлющую сеть архивов R (Comprehensive R Archive Network, аббр. CRAN), которая обеспечивает доступ к самой свежей версии и ресурсам. Для пользователей macOS: 1. Перейдите на веб-сайт CRAN1. 2. Кликните по Download R for macOS (Скачать R для macOS). 3. Выберите подходящую версию: – для Apple Silicon (например, M1, M2) надо скачать версию, в названии которой указано «-arm64» (например, R-4.2.2-arm64.pkg); – для компьютеров Mac на базе Intel надо выбрать версию без «-arm64» (например, R-4.2.2.pkg). 4. Следуйте инструкциям мастера установки. Обычно достаточно стандартных настроек. Для пользователей Windows: 1. Перейдите на веб-сайт CRAN. 2. Выберите Download R for Windows (Скачать R для Windows). 3. Выберите base (базовая), а затем первую ссылку в верхней части страницы (например, Download R-4.2.2 for Windows). 4. Установщик проведет вас по всему процессу. В целях более эффективной установки придерживайтесь стандартных настроек. 1 См. https://cran.r-project.org/.
Установка языка R и среды RStudio  21 5. Кроме того, пользователям Windows следует скачать инструментарий Rtools, который необходим для компиляции пакетов из исходных текстов. Перейдите в Rtools по адресу, указанному в сноске1, сопоставьте версию Rtools с вашей версией языка R и следуйте инструкциям по установке. Скачивание и установка среды RStudio Интегрированная среда разработки RStudio предоставляет удобный интерфейс для R, похожий на тот, который Microsoft Word предлагает для работы с текстом, но адаптированный к скриптам R.   Для того чтобы скачать среду RStudio, перейдите на страницу скачивания RStudio2.   Кликните по DOWNLOAD RSTUDIO DESKTOP FOR WINDOWS (Скачать RStudio Desktop для Windows) или выберите свою операционную систему, чтобы получить подробные инструкции. Конфигурирование среды RStudio Воспользуйтесь приведенными ниже советами по начальной настройке, чтобы улучшить работу со средой RStudio.   Изменение темы: измените предустановленную тему на темную, чтобы улучшить удобочитаемость. Перейдите в меню Tools → Global Options → Appearance (Инструменты → Глобальные параметры → Внешний вид) и выберите Dracula (Дракула). Кликните Apply (Применить).   Установка шрифта Fira Code: для создания современного стиля программирования установите шрифт Fira Code, который поддерживает программные лигатуры. Соответствующие инструкции можно найти на странице Fira Code на GitHub3. После установки примените этот шрифт в среде RStudio в разделе Appearance (Внешний вид). Установка пакетов Пакеты расширяют функциональность языка R. Они легко устанавливаются с помощью команд в консоли RStudio: 1 2 3 См. https://cran.r-project.org/bin/windows/Rtools/. См. https://posit.co/download/rstudio-desktop/. См. https://github.com/tonsky/FiraCode/wiki/Installing.
22  Установка языка R и среды RStudio # Установить один пакет install.packages("tidyverse") # Установить несколько пакетов install.packages(c("tidyverse", "gapminder")) Для того чтобы использовать установленные пакеты, их нужно загрузить в свой сеанс: library(tidyverse) Установив язык R и среду RStudio, теперь давайте рассмотрим некоторые основополагающие методы работы с данными на языке R.
ЧАСТЬ I Работа с данными
Глава 1 Манипулирование данными В анализе данных визуализация данных и манипулирование данными необходимы для понимания и передачи сложной информации. R, как мощный язык программирования для анализа данных, предлагает целый ряд пакетов, которые позволяют создавать визуально привлекательные графики и упрощать манипулирование данными. Одной из наиболее удобных в использовании и широко применяемых коллекций пакетов на языке R1 является пакет tidyverse, разработанный Хэдли Уикхемом, главным научным сотрудником компании Posit (RStudio). Пакет tidyverse включает в себя подпакеты, которые охватывают все распространенные задачи и устанавливаются командой install.packages("tidyverse"), а активируются командой library("tidyverse"). В этом введении будут рассмотрены основы пакета tidyverse, используя подпакет readr для чтения данных, подпакет dplyr для манипулирования данными, подпакет tidyr для приведения данных в порядок и, далее в книге, подпакет ggplot2 для визуализации данных. Дополнительную информацию о пакете tidyverse можно получить, посетив его веб-сайт https://www.tidyverse.org/. 1.1. Основы Давайте начнем с нескольких фундаментальных понятий! Язык R можно использовать в качестве простого калькулятора. # Символ "#" используется для объявления комментариев! 2+2 1 Пакет – это набор предварительно написанных функций, данных и документации, которые расширяют возможности языка программирования R при решении конкретных задач.
Основы  25 #> [1] 4 2*4 #> [1] 8 2^8 #> [1] 256 (1 + 3) / (3 + 5) #> [1] 0.5 log(10) # Вычисляет натуральный логарифм числа 10! #> [1] 2.302585 R позволяет определять переменные и выполнять на них операции. Для присвоения значений имени переменной можно использовать как =, так и <-, хотя во избежание путаницы и некоторых ошибок предпочтительнее использовать символ <-. x <- 2 # Эквивалентно x=2 x*4 #> [1] 8 Инструкция x <- 2 присваивает переменной x значение 2. Таким образом, когда впоследствии мы набираем x*4, R заменяет x на 2, чтобы вычислить 2*4 и получить 8. Значение переменной x можно обновлять по мере необходимости с помощью символа = или <-. Следует учитывать, что язык R чувствителен к регистру, поэтому X и x распознаются как разные переменные. x #> [1] 2 (x <- x * 5) # Обертывание в (...) распечатывает переменную #> [1] 10 В целях более подробного ознакомления с операциями в языке R в следующей ниже таблице представлен полный перечень базовых арифметических операций, операций сравнения и логических операций, которые могут вам понадобиться. Оператор + * / Описание Сложение Вычитание Умножение Деление Пример 3+2 5-2 3*2 6/2 Результат 5 3 6 3
26  Манипулирование данными Оператор ˆ %% %/% == != < > <= >= & | ! Описание Возведение в степень Модуль (остаток числа) Целочисленное деление Равно Не равно Меньше Больше Меньше или равно Больше или равно Логическое И Логическое ИЛИ Логическое НЕ Пример 2ˆ3 5 %% 2 5 %/% 2 2 == 2 2 != 3 2<3 3>2 2 <= 2 2 >= 2 TRUE & FALSE TRUE | FALSE !TRUE Результат 8 1 2 TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE FALSE 1.1.1. Типы данных Язык R поддерживает большое количество типов и классов данных, включая кадры данных data.frames, которые похожи на электронные таблицы Excel со столбцами и строками. Сначала мы обследуем векторы. Векторы могут хранить несколько значений одинакового типа, самыми основными из которых являются числовые, символьные и логические. x #> [1] 10 class(x) #> [1] "numeric" (true_or_false <- TRUE) #> [1] TRUE class(true_or_false) #> [1] "logical" (name <- "Parsa Rahimi") #> [1] "Parsa Rahimi" class(name) #> [1] "character" Обратите внимание, что имя хранится в виде односимвольного строкового литерала. Если желательно хранить имя и фамилию в одном и том же объекте обособленно, то можно использовать конструкцию c(), чтобы конкатенировать объекты похожих классов в вектор.
Основы  27 (name_surname <- c("Parsa", "Rahimi")) #> [1] "Parsa" "Rahimi" length(name) #> [1] 1 length(name_surname) #> [1] 2 Заметьте, что длина name равна 1, а длина name_surname равна 2! Давайте создадим числовой вектор и выполним на нем несколько операций! (i <- c(1, 2, 3, 4)) #> [1] 1 2 3 4 i + 10 # Прибавляет 10 к каждому элементу #> [1] 11 12 13 14 i * 10 # Умножает каждый элемент на 10 #> [1] 10 20 30 40 # Складывает два элемента в соответствующих позициях i + c(2, 4, 6, 8) #> [1] 3 6 9 12 Вышеуказанные операции не изменяют i. Результаты не сохраняются, а просто печатаются. Если желательно сохранить результаты, то нужно присвоить их переменной. name #> [1] "Parsa Rahimi" name <- i + c(5, 4, 2, 1) name #> [1] 6 6 5 5 Обратите внимание, что переменная name больше не равна "Parsa Rahimi». Она была перезаписана числовым вектором, а не строковым литералом. Во избежание ошибок следует выполнять числовые операции только на числовых объектах. Функция str() может использоваться, например, для получения структуры объекта, такой как тип и длина. name_surname + 2 #> Error in name_surname + 2: nonnumeric argument to binary operator str(name_surname) #> chr [1:2] "Parsa" "Rahimi"
28  Манипулирование данными 1.2. Скачивание данных Если вы привыкли к базовому языку R (то есть к функциям, которые поставляются с R при установке), то, возможно, знакомы с функцией read. csv(). Однако подпакет readr, входящий в состав пакета tidyverse, предлагает функции, которые решают распространенные задачи, связанные с функция­ ми чтения в базовом R. Функция read_csv() подпакета не только загружает данные в десять раз быстрее, чем функция read.csv() базового языка R, но и создает тиббл (tibble) вместо кадра данных и позволяет избегать нестыковок базовой версии. Наверняка вы спросите, что же такое тиббл. Тиббл – это особый вид кадра данных, обладающий рядом преимуществ, таких как более быстрое время загрузки, поддержка вариантов ввода данных, возможность использования столбцов в качестве списков, нестандартные имена переменных и отсутствие создания имен строк. Для того чтобы загрузить свои данные, сначала необходимо узнать путь к ним. Нужно найти свой файл, узнать его местоположение, а затем скопировать и вставить его. Если вы – пользователь Windows, то путь может содержать экранирующие символы \. В целях исправления замените \ на /. Копирование пути дает абсолютный путь (например, /Users/User/Documents/ your_project/data/file.csv), но также можно использовать относительный путь из папки проекта (например, /data/file.csv). Давайте прочитаем данные! Применение выражения readr:: задает пакет, который будет использоваться. 1.2.1. Пример данных В приведенном ниже примере мы будем использовать реальный образец из эксперимента «Климат и сотрудничество», проведенного в Мексике. В ходе эксперимента испытуемым было предложено пройти три серии тес­тов «Мат­рицы Равена», четыре игры в диктатора и одну лотерею в помещениях с различной температурой. В основном мы будем использовать результаты игр «Матрицы Равена», которые состоят из 3 сетов по 12 матриц. Первый сет, pr_, представляет собой сдельный раунд, в котором участники получали баллы за каждую правильно решенную матрицу. Второй сет, tr_, представляет собой турнирный раунд, в котором участники соревновались со случайным соперником. Победитель получал двойные очки, а проигравший не получал ничего. Третий сет, ch_, представляет собой выборочный раунд, в котором участники выбирают, будут ли они играть в сдельном или в турнирном раунде против соперника, отличного от того, который был в турнирном раунде.
Скачивание данных  29 Данные находятся в каталоге data репозитория GitHub. Для доступа к нему и управления им потребуется пакет tidyverse. Этот пакет включает в себя несколько подпакетов, включая подпакет readr. library(tidyverse) # Скачать данные из GitHub data <- readr::read_csv( "https://raw.githubusercontent.com/nikitoshina/quarto_book/main/ → mexico_sample_data.csv" ) Для того чтобы взглянуть краем глаза на данные, можно воспользоваться функцией glimpse(), которая предоставит выборку и тип столбца. Еще один распространенный подход состоит в использовании функции head(), чтобы получить вырезку из верхних строк, или функции tail(), чтобы получить вырезку из нижних строк. Просмотр всего набора данных осуществляется посредством функции View(). data %>% glimpse() #> #> #> #> #> #> #> #> #> #> #> Rows: 114 Columns: 9 $ id $ mean_temp_celsius $ gender $ pr_correct $ tr_correct $ ch_tournament $ ch_correct $ version $ treatment <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> "001018001", "001018002", "001018005", "001018009", ~ 28.58772, 28.58772, 28.58772, 28.58772, 28.58772, 28~ "Female", "Male", "Male", "Male", "Male", "Female", ~ 7, 5, 6, 1, 7, 2, 6, 7, 5, 6, 8, 2, 2, 5, 6, 5, 2, 6~ 3, 6, 7, 5, 9, 7, 6, 7, 4, 7, 6, 3, 6, 7, 8, 6, 6, 8~ 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0~ 9, 4, 7, 7, 10, 5, 7, 6, 4, 4, 8, 6, 5, 6, 6, 6, 5, ~ "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A~ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1~ Набор данных содержит 114 строк и 9 столбцов, а также типы данных, детализирующие результаты испытуемых и варианты выбора, которые они делали в ходе эксперимента:   id – уникальный идентификационный номер испытуемого, site_id. session_n.subject_n (001.001.001);   mean_temp_celsius – средняя температура за время сеанса;   gender – пол испытуемого;   pr_correct – количество правильных ответов в сдельном раунде;   tr_correct – количество правильных ответов в турнирном раунде;   ch_correct – количество правильных ответов в выборочном раунде;   ch_tournament равно 1, если участник решил играть в турнирном раунде, и 0, если нет;   version – "A" или "B"; эта переменная нас не интересует;   treatment (воздействие или процедура) равно 1, если температура была выше 30 градусов Цельсия, и 0, если ниже.
30  Манипулирование данными 1.3. Простейшие методы управления данными с помощью подпакета dplyr В подпакете dplyr используется набор глаголов, которые служат для управления данными и передаются по конвейеру (цепочке) друг в друга с помощью конвейерного оператора %>% из пакета magrittr. В базовом R применение функций сводится к обертыванию новой функции вокруг предыдущей, например k(g(f(x))), где x обрабатывается функцией f(), затем функцией g() и, наконец, функцией k(). При таком подходе зачастую быстро становится трудно их читать по мере накопления функций и их аргументов. В целях преодоления этой проблемы мы будем использовать конвейеры x %>% f() %>% g() %>% k()! Теперь можно ясно увидеть, что мы берем переменную x и применяем к ней f(), потом g() и затем k(). Примечание 1.1. Базовый язык R теперь также имеет свой собственный конвейер |>, но мы будем придерживаться конвейера %>%. 1.3.1. Функция select() Функция select() выбирает только те столбцы, которые нужны, удаляя все остальные. При этом можно использовать позицию столбца (с номерами) или имя. Столбцы будут появляться на экране в том порядке, в котором вы их перечисляете. Мы выберем столбцы subject_id, mean_temp_celsius, gender и результаты игр «Матрицы Равена», исключив столбцы version и treatment. data_raven <- data %>% select( id, mean_temp_celsius, gender, pr_correct, tr_correct, ch_tournament, ch_correct ) tail(data_raven) #> #> #> #> #> #> #> #> #> # A tibble: 6 x 7 id mean_temp_celsius <chr> <dbl> 1 00102~ 30.5 2 00102~ 30.5 3 00102~ 30.5 4 00102~ 30.5 5 00102~ 30.5 6 00102~ 30.5 gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> Female 6 8 1 6 Male 6 5 0 3 Male 6 6 1 4 Female 6 7 0 6 Female 6 7 0 5 Male 4 7 0 7 Также с помощью функции select() можно исключать столбцы либо выбирать все остальные, используя символ -. data_raven %>% select(-gender) %>% # Выбирает все столбцы, за исключением "gender" head() # Выводит на экран первые несколько строк
Простейшие методы управления данными с помощью подпакета dplyr  31 #> #> #> #> #> #> #> #> #> # A tibble: 6 x 6 id mean_temp_celsius pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> <dbl> 1 001018001 28.6 7 3 1 9 2 001018002 28.6 5 6 0 4 3 001018005 28.6 6 7 0 7 4 001018009 28.6 1 5 1 7 5 001018010 28.6 7 9 1 10 6 001018013 28.6 2 7 0 5 1.3.2. Функция filter() Функция filter() помогает оставлять только те строки, которые нужны, на основе определенных правил. Например, здесь она используется, чтобы создать две отдельные группы данных: одну для мужчин, а другую для женщин. Символ == используется для проверки на взаимно однозначное равенство. Также можно использовать такие символы, как <, <=, >, >= и %in%. Символ %in% является специальным – он проверяет, является ли значение частью списка. data_male <- data_raven %>% filter(gender == "Male") data_female <- data_raven %>% filter(gender == "Female") head(data_male) #> #> #> #> #> #> #> #> #> # A tibble: 6 x 7 id mean_temp_celsius <chr> <dbl> 1 00101~ 28.6 2 00101~ 28.6 3 00101~ 28.6 4 00101~ 28.6 5 00101~ 30.7 6 00101~ 30.7 gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> Male 5 6 0 4 Male 6 7 0 7 Male 1 5 1 7 Male 7 9 1 10 Male 6 7 1 4 Male 5 6 1 6 head(data_female) #> #> #> #> #> #> #> #> #> # A tibble: 6 x 7 id mean_temp_celsius <chr> <dbl> 1 00101~ 28.6 2 00101~ 28.6 3 00101~ 28.6 4 00101~ 28.6 5 00101~ 30.7 6 00101~ 30.7 gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> Female 7 3 1 9 Female 2 7 0 5 Female 6 6 0 7 Female 7 7 0 6 Female 5 4 0 4 Female 8 6 1 8 При этом несколько критериев можно выстраивать в цепочку. В следующем ниже примере мы отфильтровываем мужчин в условиях температуры выше 30 градусов по Цельсию и женщин в условиях температуры ниже 30 градусов по Цельсию. При этом & используется в качестве «и», | используется в качестве «или», а условия заключаются в круглые скобки, чтобы избежать путаницы.
32  Манипулирование данными Примечание 1.2. Я задал pillar.print_min = 5, поэтому при печати столбцов будет появляться только пять строк (вместо десяти по умолчанию), в результате чего после каждого вызова не нужно использовать функцию head(). data_raven %>% filter( (gender == "Male" & mean_temp_celsius > 30) | (gender == "Female" & mean_temp_celsius < 30) ) #> #> #> #> #> #> #> #> #> # A tibble: 61 x 7 id mean_temp_celsius <chr> <dbl> 1 00101~ 28.6 2 00101~ 28.6 3 00101~ 28.6 4 00101~ 28.6 5 00101~ 30.7 # i 56 more rows gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> Female 7 3 1 9 Female 2 7 0 5 Female 6 6 0 7 Female 7 7 0 6 Male 6 7 1 4 1.3.3. Функция arrange() Функция arrange() упорядочивает таблицу, используя переменную. Например, для того чтобы взглянуть на испытуемого с наименьшим баллом в pr_ correct, используется следующее ниже написание: data_raven %>% arrange(pr_correct) #> #> #> #> #> #> #> #> #> # A tibble: 114 x 7 id mean_temp_celsius gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 1 00101~ 28.6 Male 1 5 1 7 2 00101~ 28.6 Female 2 7 0 5 3 00101~ 30.7 Female 2 3 0 6 4 00101~ 30.7 Female 2 6 0 5 5 00101~ 30.7 Male 2 6 1 5 # i 109 more rows Для сортировки в убывающем порядке применяется модификатор desc(). Например, для того чтобы найти испытуемого с наивысшим баллом в pr_correct, используется data_raven %>% arrange(desc(pr_correct)) #> # A tibble: 114 x 7 #> id mean_temp_celsius gender pr_correct tr_correct ch_tournament ch_correct
Простейшие методы управления данными с помощью подпакета dplyr  33 #> #> #> #> #> #> #> 1 2 3 4 5 # <chr> 00101~ 00102~ 00102~ 00102~ 00102~ i 109 more rows <dbl> 30.7 31.6 31.6 30.4 26.8 <chr> Female Male Male Male Male <dbl> 8 8 8 8 8 <dbl> 6 6 7 4 9 <dbl> 1 1 0 0 1 <dbl> 8 5 7 7 9 1.3.4. Функция mutate() Функция mutate() добавляет новые столбцы или видоизменяет существующие в наборе данных. Например, можно создать набор данных с четырьмя строками и добавить три новых столбца переменных: tibble(rows = 1:4) %>% mutate( One = 1, Comment = "Something", Approved = TRUE ) #> #> #> #> #> #> #> # A tibble: 4 rows One <int> <dbl> 1 1 1 2 2 1 3 3 1 4 4 1 x 4 Comment <chr> Something Something Something Something Approved <lgl> TRUE TRUE TRUE TRUE Функцию mutate() можно использовать для создания новых переменных с использованием существующих. Например, можно конвертировать градусы Цельсия в градусы Фаренгейта, рассчитать улучшение результатов турнирного раунда по сравнению с результатами в сдельном раунде и проверить отклонение от среднего значения в сдельном раунде: data_raven %>% mutate( mean_temp_fahrenheit = (mean_temp_celsius * 9 / 5) + 32, improvement = tr_correct – pr_correct, pr_deviation = pr_correct – mean(pr_correct), .keep = "none" # Оставить только недавно созданные столбцы ) #> #> #> #> #> #> #> #> #> # A tibble: 114 x 3 mean_temp_fahrenheit improvement pr_deviation <dbl> <dbl> <dbl> 1 83.5 -4 1.66 2 83.5 1 -0.342 3 83.5 1 0.658 4 83.5 4 -4.34 5 83.5 2 1.66 # i 109 more rows
34  Манипулирование данными Обратите внимание, как в функцию mutate() встраиваются функции, чтобы сначала вычислить среднее значение для всего столбца, а затем вычесть его из pr_correct. 1.3.5. Функция case_match() Функция case_match() используется для перекодирования или замены конкретных значений в переменной на основе заданного набора условий совпадения. Например, case_match() можно использовать для упрощения категоризации данных, заменив "Male" на "M", а "Female" на "F". data_raven <- data_raven %>% mutate(gender = case_match(gender, "Male" ~ "M", "Female" ~ "F")) 1.3.6. Функция summarize() Функция summary() редуцирует все строки к одностроковой сводке. Ее можно использовать для расчета процента участников мужского пола, среднего балла в сдельном раунде, максимального балла в турнире, процента людей, выбравших турнир в выборочном раунде, и среднего балла в выборочном раунде. В подпакет dplyr версии 1.0.0 была введена функция reframe(). В отличие от функции summary(), функция reframe() может выводить несколько строк. Функцию summary() следует применять в ситуациях, когда ожидается, что в каждой группе будет одна строка, а функцию reframe() – для нескольких строк. data_raven %>% summarize( # n() возвращает количество строк prop_male = sum(gender == "M", na.rm = TRUE) / n(), pr_median = median(pr_correct), tr_max = max(tr_correct), ch_ratio = sum(ch_tournament) / n(), ch_mean = mean(ch_correct) ) #> # A tibble: 1 x 5 #> prop_male pr_median tr_max ch_ratio ch_mean #> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 0.482 5 9 0.456 6.01 1.3.7. Функция group_by() Функция group_by() группирует данные по конкретным переменным для последующих операций. Комбинируя функции group_by() и summary(), можно вычислять разные сводные статистические показатели для полов!
Простейшие методы управления данными с помощью подпакета dplyr  35 data_raven %>% drop_na(gender) %>% group_by(gender) %>% summarize( pr_mean = mean(pr_correct), tr_mean = mean(tr_correct), ch_mean = mean(ch_correct), pr_sd = sd(pr_correct), n = n() ) #> # A tibble: 2 x 6 #> gender pr_mean tr_mean ch_mean pr_sd n #> <chr> <dbl> <dbl> <dbl> <dbl> <int> #> 1 F 5.22 6.17 5.93 1.58 58 #> 2 M 5.47 6.4 6.09 1.59 55 Теперь давайте сгруппируем данные по полу и выбору в выборочном раунде, чтобы посмотреть на баллы в выборочном раунде! data_raven %>% drop_na(gender) %>% group_by(gender, ch_tournament) %>% summarize( ch_mean = mean(ch_correct), pr_sd = sd(ch_correct), n = n() ) #> #> #> #> #> #> #> #> # A tibble: 4 x 5 # Groups: gender [2] gender ch_tournament ch_mean pr_sd n <chr> <dbl> <dbl> <dbl> <int> 1 F 0 5.73 1.70 33 2 F 1 6.2 1.73 25 3 M 0 6.07 1.69 29 4 M 1 6.12 2.25 26 1.3.8. Функция ungroup() Функция ungroup() снимает группировку. Во избежание путаницы следует всегда разгруппировывать данные после выполнения операций, которые требовали группировки. Следующий ниже исходный код отфильтровывает пропущенные гендерные данные из кадра данных data_raven, группирует по полу, вычисляет количество в каждой группе, затем определяет долю мужчин в каждой группе и, наконец, удаляет группировку. Примечание 1.3. Функция summary удаляет из группировки последнюю переменную, поэтому в данном случае функция ungroup вставлена исключительно в демонстрационных целях.
36  Манипулирование данными data_raven %>% drop_na(gender) %>% group_by(gender) %>% mutate(n = n()) %>% summarize(mean_male = mean(gender == "M")) %>% ungroup() #> # A tibble: 2 x 2 #> gender mean_male #> <chr> <dbl> #> 1 F 0 #> 2 M 1 Обратите внимание, что значение mean_male (отношение числа мужчин к общему числу) равно 0 для женщин и 1 для мужчин. Это обусловлено тем, что данные были сгруппированы, и мы выполняли операции на мужчинах и женщинах по отдельности. data_raven %>% drop_na(gender) %>% group_by(gender) %>% mutate(n = n()) %>% ungroup() %>% summarize(mean_male = mean(gender == "M")) #> # A tibble: 1 x 1 #> mean_male #> <dbl> #> 1 0.487 На этот раз мы разгруппировали данные перед вычислением соотношения, вследствие чего был получен правильный результат! 1.3.9. Аргумент .by Операция группировки применяется часто, и необходимость многократно выполнять группировку и разгруппировку в отдельных операциях может приводить к многословию. Для решения этой проблемы в подпакете dplyr версии 1.0.0 появилось удобное средство – аргумент .by в функциях подпакета. Это усовершенствование упрощает процесс и уменьшает необходимость в чрезмерной группировке и разгруппировке. data_raven %>% drop_na(gender) %>% # То же самое, что group_by %>% mutate %>% ungroup mutate(n = n(), .by = gender) %>% summarize(mean_male = mean(gender == "M"))
Простейшие методы управления данными с помощью подпакета dplyr  37 1.3.10. Функция rowwise() Функция rowwise() позволяет группировать данные построчно. На практике могут возникать ситуации, когда требуется выполнить вычисление по строкам, а не по столбцам. Однако при попытке выполнить операцию будет получен агрегатный результат. Именно в таких ситуациях на помощь приходит функция rowwise(). Давайте создадим кадр данных со столбцом, состоящим из списков, и попытаемся определить длину каждого списка: (df <- tibble( x = list(1, 2:3, 4:6, 7:11) )) #> #> #> #> #> #> #> # A tibble: 4 x 1 x <list> 1 <dbl [1]> 2 <int [2]> 3 <int [3]> 4 <int [5]> df %>% mutate(length = length(x)) #> #> #> #> #> #> #> # A tibble: 4 x 2 x length <list> <int> 1 <dbl [1]> 4 2 <int [2]> 4 3 <int [3]> 4 4 <int [5]> 4 В приведенном выше примере вместо значений длины списков было получено общее количество строк в наборе данных (длина столбца x). Теперь давайте воспользуемся функцией rowwise(): df %>% rowwise() %>% mutate(length = length(x)) #> #> #> #> #> #> #> #> # A tibble: 4 x 2 # Rowwise: x length <list> <int> 1 <dbl [1]> 1 2 <int [2]> 2 3 <int [3]> 3 4 <int [5]> 5 При выполнении функции rowwise() R выполняет функцию length() отдельно на каждом списке, предоставляя правильные значения длины.
38  Манипулирование данными Примечание 1.4. Как вариант можно использовать векторизованную функцию lengths(), то есть данная функция применяется к каждому элементу вектора. 1.3.11. Функция count() Функция count() в R используется для подсчета количества строк в каждой группе значений, аналогично сочетанию функций group_by() и summary(). Ее можно использовать с одним столбцом для подсчета строк по полу (gender): data_raven %>% count(gender) #> #> #> #> #> #> # A tibble: 3 x 2 gender n <chr> <int> 1 F 58 2 M 55 3 <NA> 1 Как вариант ее можно использовать с несколькими столбцами, учитывающими как gender, так и ch_tournament, напоминая функциональность group_ by(gender, ch_tournament): data_raven %>% count(gender, ch_tournament) #> #> #> #> #> #> #> #> # A tibble: 5 x 3 gender ch_tournament n <chr> <dbl> <int> 1 F 0 33 2 F 1 25 3 M 0 29 4 M 1 26 5 <NA> 1 1 1.3.12. Функция rename() Функция rename() позволяет изменять имена столбцов, указывая новое имя слева, а старое – справа. Давайте заменим id на subject_id, а gender – на sex: data_raven %>% rename(subject_id = id, sex = gender) #> #> #> #> #> #> #> #> # A tibble: 114 x 7 subject_id mean_temp_celsius <chr> <dbl> 1 001018001 28.6 2 001018002 28.6 3 001018005 28.6 4 001018009 28.6 5 001018010 28.6 sex pr_correct tr_correct ch_tournament <chr> <dbl> <dbl> <dbl> F 7 3 1 M 5 6 0 M 6 7 0 M 1 5 1 M 7 9 1
Простейшие методы управления данными с помощью подпакета dplyr  39 #> # i 109 more rows #> # i 1 more variable: ch_correct <dbl> 1.3.13. Функция row_number() Функция row_number() генерирует столбец с последовательными числами, что бывает полезно для создания нового идентификаторного столбца. В следующем ниже примере сначала удаляется столбец id, а затем с помощью функции row_number() создается новый: data_raven %>% select(-id) %>% # .before = 1 помещает новый столбец "id" на первую позицию mutate(id = row_number(), .before = 1) #> #> #> #> #> #> #> #> #> # A tibble: 114 x 7 id mean_temp_celsius <int> <dbl> 1 1 28.6 2 2 28.6 3 3 28.6 4 4 28.6 5 5 28.6 # i 109 more rows gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> F 7 3 1 9 M 5 6 0 4 M 6 7 0 7 M 1 5 1 7 M 7 9 1 10 1.3.14. Функция skim() Функция skim() из подпакета skimr предоставляет обширную сводку по кад­ ру данных. Она предлагает не только функцию summary(), но и подробные квартили, пропущенные значения и гистограммы. Ее следует использовать во время разведывательного анализа данных, чтобы лучше понять данные, так как она обеспечивает четкий и всесторонний обзор каждой переменной, полезный для дальнейшего анализа. library(skimr) skim(data_raven) Таблица 1.1. Сводка по набору данных Name Number of rows Number of columns data_raven 114 7 Column type frequency: character numeric 2 5 Group variables None
40  Манипулирование данными Тип переменной: символьный (character) skim_variable n_missing complete_rate Min id 0 1.00 9 gender 1 0.99 1 Max 9 1 Empty 0 0 n_unique 114 2 Whitespace 0 0 Тип переменной: числовой skim_variable n_missing mean_temp_celsius pr_correct tr_correct ch_tournament ch_correct 0 0 0 0 0 complete_ rate 1 1 1 1 1 Mean Sd p0 p25 p50 p75 p100 Hist 30.63 5.34 6.28 0.46 6.01 26.84 1.00 3.00 0.00 2.00 30.4 5.0 6.0 0.0 5.0 30.69 5.00 6.00 0.00 6.00 31.59 6.00 7.00 1.00 7.00 32.3 8.0 9.0 1.0 10.0 1.43 1.57 1.35 0.50 1.82 1.4. Обследование даты и времени с помощью подпакета lubridate Освоить сложности, связанные с датами, временами и часовыми поясами, возможно, будет непросто, но не отчаивайтесь! Вам поможет недавно появившийся в пакете tidyverse подпакет lubridate благодаря своим замечательным возможностям упрощать манипулирование датами и временем. С помощью подпакета lubridate можно легко конвертировать строковые литералы в даты, а даты – в строковые литералы, изменять форматы, проверять наличие совпадений и выполнять арифметические операции на датах. 1.4.1. Функции ymd(), md(), hms(), ymd_hms() При работе с датами существуют различные обозначения, каждое из которых представлено комбинацией букв. Для того чтобы извлекать даты из текста, требуется лишь определить порядок следования года, месяца, дня, часов, минут и секунд, а затем применить соответствующую функцию, чтобы та сотворила свое волшебство. library(lubridate) day_year_month <- "31/2001/01" (date <- dym(day_year_month)) #> [1] "2001-01-31" month_day_year_hour_minute <- "Jan 31st 2001 6:05PM" (date_time <- mdy_hm(month_day_year_hour_minute)) #> [1] "2001-01-31 18:05:00 UTC"
Краткий итог  41 sentence_with_date <- "Elizabeth II was Queen of the United Kingdom from 6 → February 1952." # lubridate может выявлять данные внутри текста и выполнять их разбор! dmy(sentence_with_date) #> [1] "1952-02-06" 1.4.2. Функции year(), month(), day() Конкретные компоненты даты и времени можно извлекать аналогичным образом, используя функции, названные по имени элементов, которые требуется извлечь. day(date_time) #> [1] 31 hour(date_time) #> [1] 18 # label = TRUE возвращает название месяца, abbr = FALSE возвращает полное название. month(date_time, label = TRUE, abbr = FALSE) #> [1] January #> 12 Levels: January < February < March < April < May < June < ... < December 1.5. Краткий итог В данной главе были затронуты элементарные операции языка R и обследованы базовые возможности коллекции пакетов tidyverse по работе с данными. Они включали приемы загрузки элементарных данных, в том числе с датами и временем, управления ими и их обработки, что обеспечивает надежную основу для начинающих. Далее мы обсудим вопрос о том, что делает данные «упорядоченными» и как их эффективно организовывать.
Глава 2 Упорядоченные данные Приведение в порядок – это стандартный способ структурирования набора данных с целью упрощения его использования. Стандарт упорядочивания данных, в том виде, в котором он был популяризирован Хэдли Уикхемом [36], зависит от организации строк, столбцов и таблиц и от того, как они соответствуют наблюдениям, переменным и типам. В контексте упорядочивания данных: 1) каждая переменная представлена столбцом; 2) каждое наблюдение представлено строкой; 3) каждый тип наблюдаемой единицы представлен таблицей. Примечание 2.1. То, какие изменения следует внести в столбец. Данные обычно имеют два формата: широкий и длинный. Широкие данные, также именуемые неналоженными данными (unstacked data), структурированы таким образом, что каждая строка представляет отдельную единицу наблюдения, а каждый столбец – переменную. Этот формат часто используется в ситуациях, когда количество переменных относительно невелико и между ними нет иерархических отношений. Указанный формат час­ то используется в отчетах, в которых он может улучшать удобочитаемость. Ярким примером широких данных является панель, столбцы которой соответствуют годам, как показано в табл. 2.1а. Напротив, длинные данные, также именуемые наложенными данными, организованы таким образом, что каждая строка представляет собой одно наблюдение за переменной, а столбцы представляют переменную (год) и единицу измерения (численность населения в миллионах), как показано в табл. 2.1b. Этот формат обычно используется в ситуациях, когда число переменных велико или они иерархически связаны. Вы часто будете обнаруживать, что при проведении анализа управлять длинными данными гораздо удобнее. Первый пример может навести на мысль, что длинные и упорядоченные данные – синонимы. Давайте рассмотрим еще один пример, в котором мы собираемся сделать данные шире. В табл. 2.2а каждое наблюдение, включающее страну, численность ее населения и уровень рождаемости, распределено по двум строкам. В данном случае мы стремимся расширить данные, как показано в табл. 2.2b.
Краткий итог  43 Таблица 2.1. Панельные данные (а) Широкий формат Страна 2020 2021 США 329.5 331.9 Россия 144.1 143.4 Мексика 126 126.7 (b) Упорядоченный длинный формат Страна Год Численность населения США 2020 329.5 Россия 2020 144.1 Мексика 2020 126 США 2021 331.9 Россия 2021 143.4 Мексика 2021 126.7 Таблица 2.2. Беспорядочные длинные данные (а) По двум строкам Страна Название США Численность населения Россия Численность населения Мексика Численность населения США Уровень рождаемости Россия Уровень рождаемости Мексика Уровень рождаемости Величина 329.5 144.1 126 1.64 1.5 1.9 (b) Упорядоченные широкие данные Страна Численность населения Уровень рождаемости США 329.5 1.64 Россия 144.1 1.5 Мексика 126 1.9 С беспорядочными данными связана еще одна распространенная проб­ лема, которая возникает в ситуациях, когда две переменные совмещены в одном столбце, как показано в табл. 2.3a, в которой «Год» и «Численность населения» находятся в одном столбце. Их необходимо обособить, выделив для них два отдельных столбца: «Год» и «Численность населения», как представлено в табл. 2.3b. Таблица 2.3. Объединенные данные (а) Объединенные Год/Численность населения Страна Год/Численность населения США 2020/329.5 Россия 2020/144.1 Мексика 2020/126 США 2021/331.9 Россия 2021/143.4 Мексика 2021/126.7 (b) Упорядоченные данные, разбитые на столбцы Страна Год Численность населения США 2020 329.5 Россия 2020 144.1 Мексика 2020 126 США 2021 331.9 Россия 2021 143.4 Мексика 2021 126.7
44  Упорядоченные данные 2.1. Пример Упорядоченные данные – это больше, чем теоретическое понятие; они имеют практические последствия для структурирования данных. Давайте рассмотрим реальный пример хранения данных о платежах за эксперименты в формоподобной структуре: Рис. 2.1  Пример формы При чтении этих данных компьютер не способен понять наши намерения, поэтому все столбцы читаются как есть. А при добавлении еще нескольких дней потребуется создать похожие таблицы, что увеличивает вероятность ошибки. Более того, при возникновении потребности получить итоговый результат по всему эксперименту придется просуммировать все ячейки вручную. Теперь сравните это со следующим ниже: Рис. 2.2  Пример упорядоченной формы В этом формате ввод данных прост: каждая переменная имеет свой собственный столбец, а генерировать таблицы итогов так же просто, как создавать сводную таблицу. Использование упорядоченных данных с самого начала помогает создавать надежные таблицы и экономит время при анализе.
Подпакет tidyr  45 2.2. Подпакет tidyr Преобразование данных в упорядоченный формат изначально требует определенных усилий, но эта предварительная работа окупается за счет экономии времени и уменьшения осложнений в дальнейшем. Процедура упорядочивания данных легко осуществляется на языке R с помощью подпакетов пакета tidyverse, сокращая время, необходимое для манипулирования данными в различных форматах. Важно отметить, что достижение состояния «упорядоченности данных» иногда может быть неоднозначным. Главное – обес­ печить, чтобы формат данных соответствовал конкретным потребностям в анализе. В следующих далее разделах мы рассмотрим способы эффективного использования указанного упорядоченного формата данных с помощью подпакета tidyr, который является частью пакета tidyverse. 2.2.1. Функция pivot_longer() Одна из распространенных проблем возникает в наборах данных в ситуациях, когда имена столбцов являются не именами переменных, а значениями переменной. Это относится к pr_correct, tr_correct и ch_correct, где имена столбцов представляют имя переменной game. В то же время значения в столбцах представляют количество правильных ответов, а каждая строка обозначает не одно наблюдение, а три. (data_raven <- readr::read_csv( "https://raw.githubusercontent.com/nikitoshina/quarto_book/main/raven_data.csv" )) #> #> #> #> #> #> #> #> #> # A tibble: 114 x 7 id mean_temp_celsius <chr> <dbl> 1 0010~ 28.6 2 0010~ 28.6 3 0010~ 28.6 4 0010~ 28.6 5 0010~ 28.6 # i 109 more rows gender pr_correct tr_correct ch_tournament ch_correct <chr> <dbl> <dbl> <dbl> <dbl> Female 7 3 1 9 Male 5 6 0 4 Male 6 7 0 7 Male 1 5 1 7 Male 7 9 1 10 Для того чтобы привести в порядок такой набор данных, нужно развернуть (pivot) проблемные столбцы в новые пары переменных. Мы преследуем цель создать столбец для названий игр и отдельный столбец для результатов игр. Для этой операции будет использована функция pivot_longer(), которая преобразовывает данные из широкого формата в длинный. Для нее требуются следующие ниже элементы: 1) столбцы, имена которых являются значениями, а не переменными, – это столбцы, которые мы хотим развернуть. В данном случае pr_correct, tr_correct, ch_correct – значения, а game – имя переменной;
46  Упорядоченные данные 2) имя переменной, в которую мы будем перемещать имена столбцов. Здесь это game. По умолчанию используется name; 3) имя переменной, в которую мы будем перемещать значения столбцов. Здесь это n_correct. По умолчанию используется value. library(tidyr) library(dplyr) data_raven %>% pivot_longer( c(pr_correct, tr_correct, ch_correct), names_to = "game", values_to = "n_correct" ) %>% select(id, game, n_correct) #> #> #> #> #> #> #> #> #> # A tibble: 5 x 3 id game n_correct <chr> <chr> <dbl> 1 001018001 pr_correct 7 2 001018001 tr_correct 3 3 001018001 ch_correct 9 4 001018002 pr_correct 5 5 001018002 tr_correct 6 # i 337 more rows 2.2.2. Функция pivot_wider() Функция pivot_wider() является противоположностью функции pivot_longer(). Она используется в ситуациях, когда наблюдение разбросано по нескольким строкам. Например, возьмем кадр данных data_raven_accident, в котором собраны значения mean_temp_celsius и ch_tournament. В этом случае наблюдение разбросано по двум строкам. data_raven_accident #> #> #> #> #> #> #> #> #> # A tibble: 5 x 3 id name <chr> <chr> 1 001018001 mean_temp_celsius 2 001018001 ch_tournament 3 001018002 mean_temp_celsius 4 001018002 ch_tournament 5 001018005 mean_temp_celsius # i 223 more rows value <dbl> 28.6 1 28.6 0 28.6 Для того чтобы упорядочить эти данные, потребуется создать два столбца: один для mean_temp_celsius и один для ch_tournament. При этом нужны два параметра:
Подпакет tidyr  47 1) столбец, из которого будут приниматься имена переменных. Здесь это name; 2) столбец, из которого будут приниматься значения. Здесь это value. data_raven_accident %>% pivot_wider(names_from = name, values_from = value) #> #> #> #> #> #> #> #> #> # A tibble: 5 x 3 id mean_temp_celsius ch_tournament <chr> <dbl> <dbl> 1 001018001 28.6 1 2 001018002 28.6 0 3 001018005 28.6 0 4 001018009 28.6 1 5 001018010 28.6 1 # i 109 more rows Следует еще раз подчеркнуть, что, как следует из имен функций pivot_wider() и pivot_longer(), очевидно, что они являются взаимообратными. Функция pivot_longer() конвертирует широкие таблицы в более длинный и узкий формат, тогда как функция pivot_wider() конвертирует длинные таблицы в более короткий и широкий формат. 2.2.3. Функции separate() и unite() Иногда данные могут поступать с объединенными столбцами, что требует их обособления с целью поддержания упорядоченности данных. Изначальная функция separate() была заменена на функции separate_wider_position() и separate_wider_delim(), а также существуют версии семейства separate_longer_*(). Эти функции отличаются тем, как они обрабатывают обособление переменных: функции separate_wider_position() и separate_wider_delim() разделяют переменные на более широкие кадры данных, создавая больше столбцов соответственно на основе позиции или разделителя, а версии separate_longer_*() создают более длинные кадры данных, потенциально генерируя больше строк. data_raven_sep #> #> #> #> #> #> #> #> #> # A tibble: 5 x 2 id `gender/pr_correct` <chr> <chr> 1 001018001 Female/7 2 001018002 Male/5 3 001018005 Male/6 4 001018009 Male/1 5 001018010 Male/7 # i 109 more rows
48  Упорядоченные данные Кадр данных data_raven_sep содержит столбец gender/pr_correct, значения в котором отделены косой чертой, объединяя два столбца и затрудняя анализ. В целях решения этой проблемы нужно разбить столбец на две части, используя прямую косую черту /. data_raven_sep %>% separate_wider_delim( col = "gender/pr_correct", delim = "/", names = c("gender", "pr_correct") ) #> #> #> #> #> #> #> #> #> # A tibble: 5 x 3 id gender <chr> <chr> 1 001018001 Female 2 001018002 Male 3 001018005 Male 4 001018009 Male 5 001018010 Male # i 109 more rows pr_correct <chr> 7 5 6 1 7 А что, если одна переменная разбита на несколько столбцов? Рассмотрим ситуацию, когда идентификационный код испытуемого, состоящий из site_ id, session_n и subject_n, был разбит на три отдельных столбца. В таком случае нужно было бы объединить (функция unite()) эти столбцы обратно в один. data_raven_uni #> #> #> #> #> #> #> #> #> # A tibble: 5 x 4 site_id session_n <chr> <chr> 1 001 018 2 001 018 3 001 018 4 001 018 5 001 018 # i 109 more rows subject_n <chr> 001 002 005 009 010 gender <chr> Female Male Male Male Male data_raven_uni %>% unite(c(site_id, session_n, subject_n), col = "id", sep = "") #> #> #> #> #> #> #> #> #> # A tibble: 5 x 2 id gender <chr> <chr> 1 001018001 Female 2 001018002 Male 3 001018005 Male 4 001018009 Male 5 001018010 Male # i 109 more rows
Функции tibble() и tribble()  49 2.3. Функции tibble() и tribble() Как вы узнали из предыдущей главы, тиббл (tibble) в языке R представляет собой особый вид кадра данных. Тибблы – это современное переосмысление кадра данных, который сконструирован таким образом, чтобы быть более удобным и взаимоувязанным, чем традиционные кадры данных. Для его создания используется функция tibble(), аналогичная функции data.frame(). Вот некоторые особенности, которые придают тибблам уникальность:   по умолчанию тибблы выводят на экран только первые десять строк при печати, упрощая работу с крупными наборами данных;   они используют единый формат печати, упрощая работу с несколькими тибблами в одном сеансе;   тибблы имеют взаимоувязанное поведение своих подмножеств, упрощая выбор столбцов по имени. При печати указывается тип данных в каждом столбце;   при вычислении подмножества тиббла всегда возвращается тиббл, поэтому не нужно использовать drop = FALSE, как в случае с традиционными кадрами данных. tibble( x = c(1, 2, 3), y = c("one", "two", "three") ) #> #> #> #> #> #> # A tibble: 3 x 2 x y <dbl> <chr> 1 1 one 2 2 two 3 3 three Функция tribble() в языке R также используется для создания построчного удобочитаемого тиббла. Она особенно широко применяется при создании малых таблиц данных. Ее синтаксис таков: tribble(~column1, ~column2), где в первой строке задаются имена столбцов и далее построчно указываются значения. tribble( ~x, ~y, 1, "one", 2, "two", 3, "three" ) #> # A tibble: 3 x 2 #> x y #> <dbl> <chr>
50  Упорядоченные данные #> 1 #> 2 #> 3 1 one 2 two 3 three 2.4. Пакет janitor: очистка данных Пакет janitor, который не входит в состав пакета tidyverse, сконструирован для того, чтобы придать процессу очистки и упорядочения данных максимальную простоту и эффективность. Узнать больше о предоставляемых им функциях можно, ознакомившись с виньетками пакета. 2.4.1. Функция clean_names() Функция clean_names() используется для очистки имен переменных в кадрах данных, в особенности тех, которые читаются из файлов Excel с помощью функций readxl::read_excel() и readr::read_csv(). Она выполняет разбор и переводит регистры букв, разделители и специальные символы в согласующийся формат, конвертирует некоторые символы, такие как % в «процент» и # в «число», чтобы сохранить их смысл, и устраняет проблемы с повторяющимися или пустыми именами. Эту функцию рекомендуется вызывать при каждом чтении данных. Примечание 2.2. В случае неуверенности в данных рекомендуется увеличивать количество строк, используемых для определения типов столбцов. Такой подход помогает предотвращать возникновение непреднамеренных случаев пропущенных значений в данных (NA), возникающих из-за неправильно выбранных типов данных. Эта практика особенно важна при работе с данными из приложений Excel или Google Таблицы. Например, при использовании функции read_csv() можно увеличить количество строк, используемых для логического выведения типа, указав параметр guess_max: read_csv("your_file. csv", guess_max = 10^5). В качестве альтернативы можно отнести все столбцы к символьному типу, чтобы позже устранить эти проблемы вручную: read_ csv(..., col_types = cols(.default = "c")). # Создать data.frame с грязными именами df_dirty_names <- as.data.frame(matrix(ncol = 6)) names(df_dirty_names) <- c( "camelCase", "ábc@!*", "% of respondents (2009)", "Duplicate", "Duplicate", "" ) df_dirty_names %>% colnames() #> [1] "camelCase" "ábc@!*" #> [3] "% of respondents (2009)" "Duplicate" #> [5] "Duplicate" ""
Пакет janitor: очистка данных  51 library(janitor) df_dirty_names %>% clean_names() %>% colnames() #> [1] "camel_case" "abc" #> [3] "percent_of_respondents_2009" "duplicate" #> [5] "duplicate_2" "x" 2.4.2. Функция remove_empty() Функция remove_empty() удаляет пустые строки и столбцы, что особенно полезно при чтении файлов Excel. # Создать data.frame со значениями NA (not available) df_na_values <- data.frame( numbers = c(1, NA, 3), food = c(NA, NA, NA), letters = c("a", NA, "c") ) df_na_values #> numbers food letters #> 1 1 NA a #> 2 NA NA <NA> #> 3 3 NA c df_na_values %>% remove_empty(c("rows", "cols")) #> numbers letters #> 1 1 a #> 3 3 c 2.4.3. Функция remove_constant() Функция remove_constant() удаляет столбцы из data.frame, которые содержат только одно постоянное значение (с опцией na.rm, чтобы контролировать, следует ли рассматривать случаи NA как значения, отличные от константы). # Создать data.frame со столбцом, содержащим константное значение df_constant <- data.frame(cool_numbers = 1:3, boring = "the same") df_constant #> cool_numbers boring #> 1 1 the same #> 2 2 the same #> 3 3 the same df_constant %>% remove_constant()
52  Упорядоченные данные #> cool_numbers #> 1 1 #> 2 2 #> 3 3 2.4.4. Функции convert_to_date() и convert_to_ datetime() Вспомните, как вы загружали данные из Excel и вместо дат получали что-то наподобие 36922,75? Так вот, функции convert_to_date() и convert_to_datetime() конвертируют этот формат и другие форматы даты-времени в реальные даты! Если нужны дополнительные возможности по индивидуальной настройке, то следует ознакомиться с функцией excel_numeric_to_date(). convert_to_date(36922.75) # Дата #> [1] "2001-01-31" convert_to_datetime(36922.75) # Дата и время #> [1] "2001-01-31 18:00:00 UTC" 2.4.5. Функция row_to_names() Функция row_to_names() берет имена переменных, хранящихся в строке кадра данных, и делает их именами столбцов кадра данных. При желании она также может удалять строку, содержащую имена, и все строки над ней. # Создать data.frame, в котором имена столбцов находятся в строке df_row_names <- data.frame( x_1 = c(NA, "Names", 1:3), x_2 = c(NA, "Value", 4:6) ) df_row_names #> #> #> #> #> #> x_1 x_2 1 <NA> <NA> 2 Names Value 3 1 4 4 2 5 5 3 6 # Повысьте уровень строки, чтобы она стала именами столбцов row_to_names(df_row_names, 2) #> Names Value #> 3 1 4 #> 4 2 5 #> 5 3 6
Краткий итог  53 2.5. Краткий итог В этой главе была представлена концепция упорядочивания данных, при этом основное внимание уделялось их структурированному формату, в котором каждая переменная соответствует столбцу, каждое наблюдение – строке, а каждый тип единицы наблюдения – таблице. При этом были отмечены различия между широким и длинным форматами данных и представлены практические инструменты языка R, служащие для организации данных в упорядоченную структуру, включая обзор тибблов и дополнительных ресурсов для очистки данных. Понимание этих принципов упорядочивания данных имеет неоценимое значение и будет полезным на протяжении всей вашей карьеры. Далее все ваше внимание будет сосредоточено на реляционных данных и концепции соединений!
Глава 3 Реляционные данные Процесс организации данных предусматривает структурирование информации таким образом, чтобы ее было легко хранить, обновлять, извлекать и ею управлять. Одним из эффективных подходов является использование реляционных структур, которые упорядочивают данные в таблицы со строками и столбцами. В этих таблицах каждая строка представляет определенную сущность, а каждый столбец описывает определенный атрибут этой сущности. Понимание базовой структуры организации реляционных данных открывает путь к пониманию того, как эти таблицы взаимодействуют и соединены. Это взаимодействие играет решающую роль в обеспечении гибкости и мощности реляционных структур. Реальная мощь реляционного подхода заключается в изощренных со­ единениях между таблицами. Указанные отношения позволяют эффективно организовывать сложные структуры данных и выполнять запросы к ним. Понимая эти соединения, можно в полной мере использовать потенциал реляционной организации данных. Давайте углубимся в эти отношения, изучим их применение и научимся визуализировать их с помощью диаграмм. 3.1. Типы отношений 3.1.1. Отношение «один к одному» (1:1) В отношении с кардинальностью «один к одному»1 одна строка в первой таблице соответствует только одной строке во второй таблице, и наоборот. Например, отношение между странами и соответствующими им столицами: 1 Кардинальность отношения определяется количеством раз, когда сущность из одной группы находится в отношении с сущностями из другой группы. Она иллюст­ рирует связи между сущностями и то, как часто эти связи возникают.
Типы отношений  55 Страна Столица Китай Пекин Франция Париж Италия Рим Рис. 3.1  Пример отношения «один к одному» 3.1.2. Отношение «один ко многим» (1:M) В отношении с кардинальностью «один ко многим» одна строка в первой таблице может быть связана с несколькими строками во второй таблице, но строка во второй таблице связана только с одной строкой в первой таблице. Например, один учитель может вести несколько учебных занятий. Учитель Учебное занятие Хоббс 690-02 Доу 692-01 405-01 Рис. 3.2  Пример отношения «один ко многим» 3.1.3. Отношение «многие ко многим» (M:N) В отношении с кардинальностью «многие ко многим» одна строка в первой таблице может быть связана с несколькими строками во второй таблице, и точно так же строка во второй таблице может быть связана с несколькими строками в первой таблице (рис. 3.3). Например, несколько учеников могут быть зачислены на несколько учебных занятий.
56  Реляционные данные Ученик Учебное занятие Джон 690-02 Дэвид 692-01 Селеста 405-01 Рис. 3.3  Пример отношения «многие ко многим» 3.2. Понятие ключей Первичный ключ (ПК) – это уникальный идентификатор каждой строки в таб­лице; причем каждая таблица должна иметь свой ПК. Для установления отношений между таблицами первичные ключи из одной таблицы интегрируются в другую, в которой они становятся внешними ключами (ВК). Указанные ВК позволяют устанавливать связи между соотносящимися сущностями в разных таблицах. Например, в системе с учебными занятиями и учителями ключ ClassID действует как первичный для учебных занятий, а ключ ProfessorID служит внешним ключом для учителей (professors) и внешним ключом в таблице учебных занятий (classes), связывая каждое занятие с соответствующим учителем. Таблица 3.1. Ключи ClassID (ПК) 620-01 623-01 663-01 ProfessorID (ВК) 1 2 2 Credits 4 2 2 Location LM-340 UM-102 LO-234 ProfessorID (ПК) Professor 1 Арман 2 Алессандра 3.3. Типы соединений Операция соединения используется для слияния двух или более таблиц на основе столбца, соотносящегося между ними. Существует несколько типов соединений. В качестве иллюстрации принципа работы соединений мы будем использовать две таблицы: сотрудников (employees) и проектов (projects). Таблица сотрудников содержит идентификатор сотрудника (ПК) и имя, а таб­ лица проектов – идентификатор проекта (ПК) и идентификатор сотрудника (ВК).
Типы соединений  57 Таблица 3.2. Таблица сотрудников employee_id 1 2 3 4 5 name Джон Джейн Боб Элис Том Таблица 3.3. Таблица проектов project_id 1 2 3 4 5 6 employee_id 1 2 3 1 4 6 3.3.1. Внешние соединения Внешние соединения используются для возврата совпадающих данных и несовпадающих данных из одной или обеих таблиц, в результате создавая более полную таблицу. 3.3.1.1. Левое соединение При левом соединении извлекаются все строки из левой таблицы, а также совпадающие строки из правой таблицы, добавляя информацию в левую таблицу. При выполнении левого соединения оно показывает в таблицах сотрудников и проектов то, каким сотрудникам назначены какие проекты. Если в нужной таблице нет соответствующего совпадения, то результат содержит NA, указывая, например, на то, что сотруднику по имени Том проект не назначен. Таблица 1 Таблица 2 Рис. 3.4  Иллюстрация левого соединения
58  Реляционные данные left_join_result <- employees %>% left_join(projects, by = "employee_id") Таблица 3.4. Результат левого соединения employee_id 1 1 2 3 4 5 name Джон Джон Джейн Боб Элис Том project_id 1 4 2 3 5 NA 3.3.1.2. Правое соединение Правое объединение работает аналогично левому, но извлекает все строки из правой таблицы и только совпадающие строки из левой таблицы. Ниже мы выполняем правое соединение в таблицах сотрудников и проектов, показывая, какие проекты назначены каким сотрудникам. Это похоже на выполнение левого соединения между таблицами проектов и сотрудников. Возможно, что проект 6 никому не назначен. Таблица 1 Таблица 2 Рис. 3.5  Иллюстрация правого соединения right_join_result <- employees %>% right_join(projects, by = "employee_id") Таблица 3.5. Результат правого соединения employee_id 1 1 2 3 4 6 name Джон Джон Джейн Боб Элис NA project_id 1 4 2 3 5 6
Типы соединений  59 3.3.1.3. Полное объединение Полное соединение сочетает все строки как из левой, так и из правой таблиц, заполняя значениями NA несовпадающие строки. Указанное соединение дает полный обзор комбинированных данных. Ниже можно заметить, что между проектом 6 и Томом парное соединение отсутствует. Таблица 1 Таблица 2 Рис. 3.6  Иллюстрация полного соединения full_join_result <- employees %>% full_join(projects, by = "employee_id") Таблица 3.6. Результат полного соединения employee_id 1 1 2 3 4 5 6 name Джон Джон Джейн Боб Элис Том NA project_id 1 4 2 3 5 NA 6 3.3.1.4. Внутреннее соединение Внутреннее соединение возвращает только совпадающие строки между двумя таблицами, оставляя только те строки, которые совпадают в обеих таблицах, и создавая полный набор данных, в результате чего значения NA отсутствуют, потому что строки без пар были отброшены.
60  Реляционные данные Таблица 1 Таблица 2 Рис. 3.7  Иллюстрация внутреннего соединения inner_join_result <- employees %>% inner_join(projects, by = "employee_id") Таблица 3.7. Результат внутреннего соединения employee_id 1 1 2 3 4 name Джон Джон Джейн Боб Элис project_id 1 4 2 3 5 3.3.2. Фильтрация соединений 3.3.2.1. Антисоединение Антисоединение возвращает строки из левой таблицы, которые не находят совпадения в правой таблице, без добавления новых столбцов в выходные данные. Оно широко применяется для фильтрации строк на основе отсутствия совпадающих записей в другой таблице. Например, вместо того чтобы выполнять левое соединение и искать пропущенные значения, антисоединение может напрямую выявлять сотрудников, которым проект не назначен. anti_join_result <- employees %>% anti_join(projects, by = "employee_id") Сотруднику по имени Том никакой проект не назначен! Возможно, он мог бы заняться проектом 6? Таблица 3.8. Результат антисоединения employee_id 5 name Том
Визуализация отношений  61 3.3.2.2. Полусоединение Полусоединение аналогично внутреннему соединению в части выявления совпадающих строк между двумя таблицами. Однако, в отличие от внутреннего соединения, оно не добавляет новых столбцов в выходные данные. Вместо этого оно фильтрует строки из левой таблицы, которые имеют соответствующее совпадение в правой таблице. Полусоединение можно использовать, например, для фильтрации левой таблицы на основе наличия совпадающих записей в правой таблице, что позволяет видеть только тех людей, которым назначен проект. semi_join_result <- employees %>% semi_join(projects, by = "employee_id") Таблица 3.9. Результат полусоединения employee_id 1 2 3 4 name Джон Джейн Боб Элис 3.4. Визуализация отношений Для визуализации отношений в данных мы собираемся использовать унифицированный язык моделирования (Unified Modeling Language, аббр. UML). Возможно, вы впервые слышите о том, что за диаграммами стоит язык программирования. UML – это стандартная графическая нотация, используемая для описания вариантов конструктивного исполнения программного обес­ печения. Это мощный инструмент для планирования, визуализации и документирования проектов. Для описания структур, линий поведения и взаимодействий могут использоваться самые разные типы диаграмм, задействуя стандартный набор символов и обозначений. Для программирования на UML существуют отличные инструменты, такие как Mermaid и Graphviz, но я нахожу, что для пользователя более удобны веб-приложения с возможностью перетаскивания, такие как LucidChart 1 и Draw.io2. Сначала давайте представим сущность, то есть объект (место, человека, вещь), который мы хотим отслеживать. В нашем случае это будут покупатель, заказ и продукт. Каждая сущность обладает атрибутами; например, у по1 2 См. https://www.lucidchart.com. См. https://app.diagrams.net/.
62  Реляционные данные купателя есть идентификатор, имя, адрес электронной почты и т. д. У других сущностей тоже есть список атрибутов. Указанные сущности и атрибуты представлены в таблицах соответственно в виде строк и столбцов. Таблицы могут быть взаимосвязаны, и эти взаимоотношения визуализируются путем проведения линий между таблицами. Для описания этих отношений в числовых терминах используется кардинальность, аналогично обсуждению в разделе 3.1. Один Несколько Один и только один Ноль или один Один или несколько Ноль или несколько Рис. 3.8  Кардинальность Например, давайте рассмотрим взаимоотношение между покупателем и заказом. Используя минимаксный каркас, каково минимальное и максимальное количество заказов, которые может иметь покупатель? У покупателя может быть ноль заказов (min = 0) и неопределенное количество заказов (max = несколько). Таким образом, взаимоотношение между покупателем и заказом равно 0 или несколько. Теперь давайте посмотрим в обратном направлении: сколько покупателей может быть у заказа? У заказа может быть только один покупатель (min = 1, max = 1). Покупатель Заказ Рис. 3.9  Взаимоотношение между покупателем и заказом Далее давайте рассмотрим взаимоотношение между заказом и продуктом. Заказ может содержать один или несколько продуктов, и каждый продукт может находиться в нуле или нескольких заказах. Полная схема может выглядеть следующим образом:
Краткий итог  63 Покупатель Заказ Продукт Рис. 3.10  Диаграмма сущности-взаимоотношения Рекомендуется строить такую диаграмму всякий раз, когда планируется проект со сложным конструктивным исполнением. Она проясняет необходимые таблицы и их взаимоотношения. Диаграмму также можно начертить, если нет уверенности в наборе данных. Если вы хотите углубиться в эту тему, то следует ознакомиться с руководствами Lucid Software на YouTube (https:// www.youtube.com/@lucid_software). 3.5. Краткий итог В этой главе были подробно рассмотрены основы реляционных систем обработки данных, их структура, ключевые отношения и операции соединения. Помимо этого, был затронут вопрос о том, каким образом таблицы, строки и столбцы составляют основу этих систем, и обследована важная роль первичных (ПК) и внешних (ВК) ключей в связывании этих таблиц. Кроме того, были обследованы различные типы отношений и соединений. Забегая вперед, следующая глава будет посвящена практике валидации данных.
Глава 4 Валидация данных Валидация является важной частью анализа данных, которая охватывает поддержание целостности, точности и чистоты данных при выполнении вычислительных задач. Поскольку результаты анализа в значительной степени зависят от качества входных данных, важно обеспечивать надежный процесс валидации. Отсутствие такого процесса может приводить к эффекту «мусор на входе, мусор на выходе». Представьте, что вы тратите часы на анализ только для того, чтобы обнаружить повторяющуюся строку или спорадическое появление значений NA. Ключом к предотвращению таких сценариев являются регулярные проверки данных. Для выполнения этих проверок можно написать функцию или настроить конвейеры для нескольких проверок. Если требование преду­ сматривает совместное использование результатов валидации, то следует надлежащим образом генерировать отчеты. Хотя эта задача может показаться устрашающе сложной, существует масса пакетов R, а также встроенные функции, специально разработанные для существенного упрощения этой задачи. 4.1. Инспекция данных вручную Несмотря на удобство автоматизации, следует помнить, что вы не сможете справиться с тем, о чем не знаете. Иногда данные могут быть не готовы к немедленному анализу и, возможно, будут нуждаться в очистке перед валидацией. Поэтому важно открыть файлы вручную, просмотреть таблицы и их значения и провести предварительный разведывательный анализ. Исходя из моего опыта, наиболее важным шагом является тщательное обследование каждой переменной в отдельности, чтобы лучше понять их смысл и последствия. Этот тщательный процесс может занимать несколько часов, но результат будет значительным: вы получите более полное представление о наборе данных в сочетании с исчерпывающим списком аспектов, требую­ щих внимания и исправления. И наконец, следует всегда перепроверять
Улаживание проблем с данными  65 свои результаты, пересматривая выходную таблицу, что является важным, но прос­тым шагом для полноценной работы с сырыми данными. 4.2. Улаживание проблем с данными В случае проблем с данными важно остановить исполнение скрипта и предупре­дить пользователя. Базовый R предлагает несколько функций, облегчающих это. Например, функция is_numeric(), а также ее аналоги is_*() являются традиционными примерами. Весьма полезными оказываются функции потока управления, такие как if, else, stop() и логические операторы. x <- c(1, 2, 3) # Создать кадр данных с повторяющейся строкой df <- data.frame(x = c(x, 1), y = c(x * 2, 2)) # Останавливает исполнение, если тип x не является числовым if (!is.numeric(x)) stop("x is not numeric!") stopifnot(is.numeric(x)) # Прекращает, если тип x не является числовым # Останавливает процесс, если x содержит неположительные значения if (!all(x > 0)) stop("x contains non-positive values!") # Прекращает, если x имеет дубликаты if (any(duplicated(x))) stop("x contains duplicated values!") # Выдает предупреждение, если df имеет повторяющиеся строки if (any(duplicated(df))) warning("df has duplicated rows!") #> Warning: df has duplicated rows! 4.2.1. Подтверждение истинности своих условий Пакет assertr отлично подходит для совместимой с пакетом tidyverse валидации данных. Вместо того чтобы выполнять проверки вручную, можно добавлять инструкцию assert, чтобы удостоверяться в том, что ваши допущения о данных верны. Если допущение верно, то исходный код продолжает выполняться; однако в случае отказа выдается сообщение об ошибке и исполнение прекращается. Пакет assertr предоставляет функции, задающие условия, которым ваши данные должны удовлетворять:   verify(): эта функция проверяет, соблюдается ли данное логическое условие для всего набора данных. Если нет, то она прекращает исполнение и выдает ошибку;   assert(): эта функция применяет конкретную предикатную функцию (функцию, которая возвращает значение истина или ложь) к выбранным столбцам в кадре данных. Данные проходят проверку только в том случае, если все значения в этих столбцах удовлетворяют условию предикатной функции;
66  Валидация данных   insist(): подобно функции assert(), данная функция позволяет указывать функцию в качестве аргумента. Однако для этого используется генератор предикатных функций, позволяющий изменять предикат в зависимости от передаваемых данных. Например, в приведенном ниже примере он используется для вычисления стандартного отклонения и для отыскания выбросов. Пакет assertr поставляется с набором «вспомогательных» предикатных функций. Они предназначены для использования в сочетании с вышеуказанными функциями. Вот несколько таких функций: within_bounds(), not_na(), in_set(), within_n_sds() и т. д. При необходимости также можно создавать и использовать свои собственные предикатные функции. Синтаксис пакета легко интегрируется в типичный конвейер пакета tidyverse. Ниже приведен краткий пример использования встроенного набора данных mtcars, который содержит данные о расходе топлива и 10 аспектах конструктивного исполнения (дизайна) и характеристик 32 автомобилей (моделей 1973–1974 годов выпуска): library(assertr) library(magrittr) # для конвейера %>% # Загрузить встроенный в R набор данных data(mtcars) mtcars %>% verify(nrow(.) > 0) %>% # Удостовериться, что набор данных не пустой # Подтвердить истинность, что указанные типы двигателей (0,1) присутствуют assert(in_set(0, 1), vs) %>% # Обеспечить, чтобы значения mpg были в пределах стандартных отклонений insist(within_n_sds(2), mpg) #> The ``mpg'' column violates the assertion ``within_n_sds(2)'' two times: #> verb redux_fn predicate column index value #> 1 insist NA within_n_sds(2) mpg 18 32.4 #> 2 insist NA within_n_sds(2) mpg 20 33.9 #> Error: assertr stopped execution В этом примере функция verify() обеспечивает, чтобы набор данных mtcars содержал более одной строки, функция assert() выполняет проверку на наличие определенных значений типа двигателя (0 = V-образный, 1 = прямой), а функция insist() обеспечивает отсутствие выбросов – все значения находятся в пределах двух стандартных отклонений. Если какая-либо проверка завершается безуспешно, то конвейер останавливается и выдает сообщение об ошибке, что он и сделал, указывая на то, что функция insist() дважды завершилась ошибкой в столбце mpg.
Улаживание проблем с данными  67 4.2.2. Точная валидация с помощью пакета pointblank Пакет pointblank предлагает расширенные функциональные средства для построения валидационных конвейеров и генерирования отчетов. В пакете представлены так называемые объекты-агенты для непрерывной валидации, позволяющие проводить реиспользуемые валидации разных наборов данных. Благодаря своей надежной функциональности пакет pointblank идеально подходит для значительных по объему проектов, позволяя создавать валидационные конвейеры, HTML-отчеты и рассылать их заинтересованным сторонам. Далее мы создадим агента и обследуем набор данных mtcars. Стоит отметить, что использование агента не является обязательным – функции пакета можно использовать аналогично тому, как они используются в пакете assertr. пороги и действия (применять по необходимости) таблица валидационные функции Конвейерная валидация данных Та же таблица, что и в начале, но уже подвергнутая валидации Выход за пределы заданного …но лучше провести дополнительную валидацию, верно? Применить их как весь процесс… можно больше БУМ порога может завершить Рис. 4.1  Изображение рабочего потока пакета pointblank из документации Шаг 1: создать план валидации (агента) library(pointblank) agent <- create_agent( tbl_name = "a simple mtcars data validation", label = "an example of using pointblank for data validation", tbl = mtcars # прикрепить кадр данных, чтобы выполнить валидацию ) Шаг 2: конкретизировать проверки agent <- agent %>% # Проверить, что значения mpg больше 10 col_vals_gt(vars(mpg), value = 10) %>% # Проверить, что значения hp меньше или равны 300 col_vals_lte(vars(hp), value = 300) %>% # Проверить, что столбцы vs, am и absent существуют col_exists(vars(vs, am, absent)) %>% # Проверить, что в столбцах cyl и gear нет пропущенных значений col_vals_not_null(vars(cyl, gear)) таблица
68  Валидация данных Шаг 3: исполнить проверки (report <- interrogate(agent, extract_failed = T)) Обследование показало, что все проверки были правильно вычислены (EVAL), и почти все проверки прошли успешно. Исключением была одна строка, в которой произошел отказ, поскольку мощность двигателя превысила 300 лошадиных сил. Вдобавок в наборе данных нет столбца с именем absent. Соотношение PASS/FAIL (Успешно/неуспешно) можно просмотреть в соответствующих столбцах. Столбцы с непрошедшими проверками выделены цветом в левой части таблицы. Результаты можно скачать в виде CSV, что особенно удобно для коллективного использования отчета вместе с другими. Помимо это, есть встроенная функциональность рассылки отчета по электронной почте. Для того чтобы обследовать отказавшие строки, надо установить параметр extract_failed = TRUE и обратиться к этим строкам посредством $extracts. Ниже показана отказавшая строка: 335 лошадиных сил, что указывает на очень скоростную машину (Maserati Bora)! Рис. 4.2  Результат работы пакета pointblank report$extracts$2 # 2 ссылается на проверочное число #> # A tibble: 1 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 15 8 301 335 3.54 3.57 14.6 0 1 5 8
Краткий итог  69 4.3. Краткий итог В этой главе вы узнали, что при анализе данных валидация имеет крайне важное значение и играет ключевую роль в поддержании целостности, точности и чистоты данных. Этот процесс требует регулярных проверок, которые можно автоматизировать с помощью функций потока управления, а также пакетов assertr и pointblank языка R. Несмотря на эффективность автоматизации, ручная инспекция по-прежнему играет значительную роль и должна быть начальным шагом в процессе валидации. Обеспечение валидации ваших данных имеет существенное значение для предоставления высококачественных входных данных в отчеты. В следующей главе будут рассмотрены стратегии работы с пропущенными значениями.
Глава 5 Восполнение пропущенных данных Восполнение пропущенных данных (или импутация) – это статистический метод, который заменяет пропущенные или неполные данные путем вычисления значений на основе существующей информации, однако его противоречивый характер связан с введением искусственных данных, что потенциально влияет на результаты анализа, поскольку воссозданным вставленным данным присваивается больший вес. В этой главе будут рассмотрены типы пропущенных данных и различные способы работы с ними. Примечание 5.1. Как и в медицине, самым лучшим решением проблемы пропущенных данных является предотвращение таких ситуаций! 5.1. Типы пропущенных данных Крайне важно понимать тип пропущенных данных, так как это помогает в выборе надлежащих методов восполнения пропущенных данных или стратегий их обработки, чтобы свести к минимуму потенциальные погрешности в анализе. 1. П  олностью случайный пропуск данных (Missing Completely at Random, аббр. MCAR): пропуск данных является полностью случайным, и вероятность пропуска данных одинакова для всех наблюдений, независимо от наблюдаемых или ненаблюдаемых значений. Сценарий полностью случайного пропуска данных идеален, поскольку пропущенные данные не зависят от каких-либо других переменных в наборе данных, например от того, что садится батарейка термометра и в течение сеанса температура не регистрируется. 2. Случайный пропуск данных (Missing at Random, аббр. MAR): данные пропущены случайно, когда их отсутствие связано именно с наблюдае-
Работа с пропущенными данными  71 мыми, а не с ненаблюдаемыми переменными в наборе данных. Случайный пропуск данных можно было бы увидеть, если бы мужчины реже отвечали на вопросы опроса о психическом здоровье, чем женщины. 3. Неслучайный пропуск данных (Missing Not at Random, аббр. MNAR): неслучайный пропуск данных связан с ненаблюдаемыми значениями. Вероятность пропуска данных зависит от переменных, которые пропущены. Например, заядлые курильщики могут пропустить раздел, посвященный здоровью легких, что приведет к искажению результатов опроса. 4. Преднамеренный пропуск данных: данные пропущены преднамеренно, когда конкретные данные опускаются по изначальному замыслу, часто в рамках плана исследования или процесса сбора данных. В таких случаях пропущенные данные носят систематический характер и имеют определенную цель. Прежде чем обращаться к пропущенным данным, нередко важно научиться проводить различие между разными типами пропусков в данных. Явное обозначение пропущенных данных как NA в R помогает выявлять закономерности и соответствующим образом обрабатывать случаи пропущенных значений. 5.2. Работа с пропущенными данными Существует несколько способов обработки пропущенных данных. 1. Оставлять как есть: в некоторых случаях бывает целесообразным оставлять пропуски как есть, если они не оказывают существенного влияния на анализ. 2. Отбрасывать их (удаление по списку или полный анализ случая): этот подход предполагает удаление строк с пропущенными данными. Он прост и бывает полезен, если пропуск данных минимален и случаен. Однако он может приводить к потере информации, потенциальному систематическому смещению и уменьшению размера выборки. Несмотря на эти недостатки, из-за своей простоты он является распрост­ раненным методом количественных исследований. 3. Восполнять пропущенные данные: восполнение предусматривает вычисление пропущенных значений на основе наблюдаемых данных, что позволяет получать полный набор данных и обеспечивает сохранность всех случаев для анализа. Однако при неправильном выполнении этот метод приводит к систематическому смещению. 4. Задавать как фиктивную переменную или как фактор: иногда пропущенные значения можно трактовать как отдельную категорию. Это делается путем создания фиктивной переменной или конвертации переменной в фактор. При таком подходе выявляются пропущенные данные и включаются в анализ как отдельная группа.
72  Восполнение пропущенных данных Восполнение пропущенных данных, хотя и является мощным инструментом, должно применяться разумно, так как оно изменяет изначальный набор данных и может существенно влиять на результаты анализа. Важно понимать причины наличия пропусков в данных, принятые допущения и обоснование для применения методов восполнения в конкретном контексте анализа. Примечание 5.2. Использовать восполнение пропущенных данных нельзя по умолчанию. Методы восполнения должны привлекаться в рамках хорошо продуманной стратегии. 5.2.1. Явная обработка пропущенных данных с помощью функции complete() Во время работы с наборами данных важно понимать, что пропущенные значения не всегда можно идентифицировать явным образом. Эти неявные пропуски могут вводить в заблуждение относительно полноты данных, подчеркивая необходимость надлежащей идентификации и обработки. Функция complete() подпакета tidyr предлагает надежное решение. Функция complete() генерирует новый кадр данных, содержащий все возможные сочетания указанных столбцов, тем самым обеспечивая полноту данных. Этот процесс, дополненный заполнением пропущенных сочетаний предустановленными (дефолтными) значениями, снижает риск неявного отсутствия данных. Возьмем, к примеру, набор данных, отслеживающий четырех учеников, посещавших различные учебные занятия в течение трех дней. Изначально этот набор данных может показаться исчерпывающим. Однако были зарегистрированы только те ученики, которые посещали занятия, приведя к пробелу в данных по прогульщикам. В этом случае функция complete() используется для создания нового кад­ ра данных, complete_df, который включает в себя все мыслимые сочетания student_id, day и class. Этот метод обеспечивает точную регистрацию посещаемости каждого ученика каждого занятия в каждый день, независимо от несовершенств первоначальных данных. Пропущенные значения в столбце present (присутствует) по умолчанию равны FALSE, что явно указывает на незарегистрированную посещаемость. df <- tribble( ~day, ~class, 1, "English", 1, "English", 1, "English", 1, "Science", 2, "Math", 1, 2, "Math", 2, 2, "Math", 4, 2, "English", 2, "English", ~student_id, ~present, 1, T, 2, T, 4, T, 2, T, T, T, T, 4, T, 1, T,
Работа с пропущенными данными  73 3, "Math", 1, T, 3, "Math", 2, T, 3, "Math", 1, T ) #> #> #> #> #> #> #> #> #> #> #> #> #> #> #> # A tibble: 12 x 4 day class student_id present <dbl> <chr> <dbl> <lgl> 1 1 English 1 TRUE 2 1 English 2 TRUE 3 1 English 4 TRUE 4 1 Science 2 TRUE 5 2 Math 1 TRUE 6 2 Math 2 TRUE 7 2 Math 4 TRUE 8 2 English 4 TRUE 9 2 English 1 TRUE 10 3 Math 1 TRUE 11 3 Math 2 TRUE 12 3 Math 1 TRUE # Полный кадр данных со всеми сочетаниями столбцов student_id, day и class complete_df <- df %>% complete( # Сгенерировать последовательность ИД учеников, # используя уникальный ИД как максимальное значение student_id = full_seq(student_id, 1), # Создать сочетания, которые уже существуют в данных nesting(day, class), # Заполнить данные о пропуске посещения занятий значениями FALSE fill = list(present = FALSE), # Ограничить заполнение вновь созданными (ранее подразумевавшимися) записями explicit = FALSE ) %>% # Упорядочить по day, class, student_id и present arrange(day, class, student_id, present) #> #> #> #> #> #> #> #> #> #> #> #> #> #> #> #> # A tibble: 21 x 4 student_id day <dbl> <dbl> 1 1 1 2 2 1 3 3 1 4 4 1 5 1 1 6 2 1 7 3 1 8 4 1 9 1 2 10 2 2 11 3 2 12 4 2 13 1 2 class present <chr> <lgl> English TRUE English TRUE English FALSE English TRUE Science FALSE Science TRUE Science FALSE Science FALSE English TRUE English FALSE English FALSE English TRUE Math TRUE
74  Восполнение пропущенных данных #> #> #> #> #> #> #> #> 14 15 16 17 18 19 20 21 2 3 4 1 1 2 3 4 2 2 2 3 3 3 3 3 Math Math Math Math Math Math Math Math TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE Используя функцию nesting(), которая создает все сочетания имеющихся данных, внутри функции complete(), мы явно обрабатываем пропущенные данные, создавая исчерпывающий набор вложенных данных, пригодный для дальнейшего анализа. Такой подход гарантирует, что анализ будет основан на более полном и надежном наборе данных, предоставляющем точные данные о посещаемости разных учебных занятий и в разные дни. 5.2.2. Простые методы восполнения Для того чтобы обследовать различные методы восполнения пропусков, мы будем использовать набор данных airquality (качество воздуха), который содержит ежедневные замеры загрязнителей воздуха и погодных условий в Нью-Йорке в течение пятимесячного периода в 1973 году. В него входят данные о концентрации озона, солнечной радиации, температуре, скорости ветра и относительной влажности. В целях упрощения примера мы удалим все строки с пропущенными значениями Solar.R и сосредоточимся на Ozone. Мы также определим head_na для просмотра значений, которые были восполнены. head_na <- function(data) { data %>% filter(is.na(Ozone)) %>% # Отфильтровать строки с NA в столбце Ozone select(-Ozone) %>% # Исключить столбец Ozone из результатов head(5) # Вывести на экран первые 5 строк } head(airquality) #> #> #> #> #> #> #> 1 2 3 4 5 6 Ozone Solar.R Wind Temp Month Day 41 190 7.4 67 5 1 36 118 8.0 72 5 2 12 149 12.6 74 5 3 18 313 11.5 62 5 4 NA NA 14.3 56 5 5 28 NA 14.9 66 5 6 # Удалить строки с пропущенными значениями в Solar.R airquality <- drop_na(airquality, Solar.R) Мой любимый способ проверить наличие пропущенных данных состоит в использовании готовой функции из пакета visdat под названием vis_miss.
Работа с пропущенными данными  75 Она покажет распределение пропущенных данных, позволяя заранее составить данные и грани (фасеты), чтобы лучше выявить пропущенные данные. Следующий ниже график составлен по дням, и каждый месяц имеет свою собственную грань, поэтому появляется возможность увидеть закономерность пропущенных значений. Похоже, что в июне (6) было пропущено много значений для озона. airquality %>% arrange(Month, Day) %>% visdat::vis_miss(facet = Month) Рис. 5.1  График viz_miss() 5.2.2.1. Восполнение фиксированным значением Пропущенные значения заменяются заранее определенным постоянным значением. Этот метод прост и полезен, если вы считаете, что фиксированное значение достоверно отражает пропущенные данные. Корректировка с помощью фиктивной переменной Один из простых и общеприменимых методов восполнения состоит в замене пропущенных значений константой, например 0, и добавлении столбца двоичного индикатора, чтобы обозначить пропущенные записи (1 – если пропущено, 0 – если не пропущено). Благодаря этому можно сохранять все точки данных и учитывать их пропуск. Такой подход обеспечивает получение полного набора данных и позволяет модели вычислять влияние пропущенных данных с помощью дополнительного коэффициента для индикаторного столбца.
76  Восполнение пропущенных данных 5.2.2.2. Восполнение средним и медианой Восполнение средним и медианой – это методы обработки пропущенных данных путем замены пропущенных значений средним или медианным значениями, рассчитанными на основе непропущенных значений в том же столбце. Восполнение пропущенных данных средним значением проявляет свою эффективность в ситуациях, когда данные подчиняются нормальному распределению, но могут иметь асимметрию за счет выбросов, что приводит к систематически смещенным оценкам. Напротив, восполнение пропущенных данных медианой показывает более высокую устойчивость к выбросам и подходит для данных с асимметричными или экстремальными значениями. 5.2.2.3. Заполнение В некоторых случаях целесообразно заменять пропущенные данные предыдущими или последующими значениями. Этот подход особенно эффективен для наборов данных, в которых следующее доступное значение логически заменяет пропущенные, например во временных рядах или упорядоченных данных. В этой связи рекомендуется хорошо ознакомиться с функцией coalesce(), которая позволяет заменять пропущенные значения предопределенным значением или значениями из другого столбца. airquality %>% arrange(Month, Day) %>% mutate( # Восполнить фиксированным значением (в данном случае 0) imp_fixed = coalesce(Ozone, 0), Ozone_missing = is.na(Ozone), # Восполнить средним значением imp_mean = coalesce(Ozone, round(mean(Ozone, na.rm = TRUE), 2)), # Восполнить медианным значением imp_median = coalesce(Ozone, median(Ozone, na.rm = TRUE)), imp_fill = Ozone, .keep = "used" # Оставлять только "используемые" столбцы ) %>% # Заполняет пропущенные значения самым свежим непропущенным значением выше fill(imp_fill, .direction = "down") %>% head_na() #> #> #> #> #> #> 1 2 3 4 5 imp_fixed Ozone_missing imp_mean imp_median imp_fill 0 TRUE 42.1 31 8 0 TRUE 42.1 31 32 0 TRUE 42.1 31 32 0 TRUE 42.1 31 37 0 TRUE 42.1 31 37 Следует помнить, что выбор метода восполнения может существенно повлиять на результаты анализа. Прежде чем принимать решение, следует всег-
Работа с пропущенными данными  77 да учитывать характер данных, распределение пропусков и потенциальные последствия каждого метода. 5.2.2.4. k ближайших соседей Восполнение на основе k ближайших соседей (kNN) проявляет свою эффективность в наборах данных со сложными структурами, которые не улавливаются простыми методами. Указанный метод оценивает пропущенные значения, используя взаимоотношения между переменными. В частности, kNN определяет k ближайших точек данных (соседей) на основе показателей сходства, таких как евклидово расстояние, и использует их значения для восполнения пропущенных данных. Этот метод особенно полезен в ситуациях, когда данные демонстрируют сложные закономерности или зависимости, что позволяет более точно восполнять пропущенные данные с учетом контекста. # Восполнение на основе kNN с использованием пакета VIM library(VIM) airquality_knn <- kNN(airquality) airquality_knn %>% slice(which(is.na(airquality$Ozone))) %>% select("Ozone") %>% head(n=5) #> #> #> #> #> #> 1 2 3 4 5 Ozone 16 11 32 40 32 5.2.2.5. Регрессия Восполнение пропущенных данных на основе регрессии широко используется в ситуациях, когда между переменными существуют взаимоотношения, которые способна уловить регрессионная модель. Этот метод предусматривает предсказывание пропущенных значений на основе наблюдаемых значений у других переменных в наборе данных. Подгонка регрессионной модели, такой как линейная регрессия, к имеющимся данным позволяет вычислять пропущенные значения, используя установленные взаимоотношения. Этот подход особенно эффективен в ситуациях, когда данные демонстрируют четкие и предсказуемые ассоциации между переменными, что позволяет восполнять данные более точно. # Выполнить подгонку линейно-регрессионной модели model <- lm(Ozone ~ ., data = airquality) # Предсказать пропущенные значения predicted_values <- predict(model, newdata = airquality)
78  Восполнение пропущенных данных # Заменить пропущенные значения предсказанными значениями airquality %>% mutate( Ozone = Ozone, imp_lm = ifelse(is.na(Ozone), predicted_values, Ozone), .keep = "used" ) %>% head_na() #> #> #> #> #> #> 1 2 3 4 5 imp_lm 35.446534 -16.177404 1.688479 51.628995 40.719713 5.2.2.6. Лес Методы на основе деревьев, такие как случайные леса, эффективны для обработки сложных структур данных с нелинейными взаимоотношениями или взаимодействиями между переменными. Указанные методы могут улавливать замысловатые закономерности в данных, что делает их хорошим вариантом выбора для восполнения пропущенных данных в ситуациях, когда более простые методы не работают. Однако методы на основе деревьев нередко оказываются малоэффективными с малыми размерами выборки или разреженными данными, поскольку для построения точных моделей им требуется определенный объем информации. Несмотря на это ограничение, их способность моделировать сложные взаимоотношения делает их мощным инструментом для восполнения пропущенных данных во многих сценариях. # Установить и загрузить пакет missForest library(missForest) airquality %>% mutate( Ozone = Ozone, imp_forest = missForest(.)$ximp$Ozone, .keep = "used" ) %>% head_na() #> #> #> #> #> #> 1 2 3 4 5 imp_forest 22.250 14.465 25.110 32.690 25.560 Следует помнить, что каждый из этих методов имеет свои сильные и слабые стороны, и при выборе метода нужно руководствоваться характером
Работа с пропущенными данными  79 данных и конкретными требованиями к анализу. Необходимо всегда сверяться с допущениями, используемыми в методе восполнения, и учитывать их потенциальное влияние на результаты. 5.2.3. Наилучший сценарий из наихудших и наихудший сценарий из наилучших Простейший метод оценивания воздействия пропущенных данных состоит в их замене как наихудшими, так и наилучшими из возможных исходов. В клинических испытаниях обычно предполагается, что контрольная группа достигнет положительного исхода, рассчитанного как среднее значение плюс два стандартных отклонения, тогда как в группе, подвергающейся медикаментозному воздействию, будет наблюдаться неблагоприятный исход, рассчитанный как среднее значение минус два стандартных отклонения. Этот метод создает два новых ряда данных, один из которых отражает оптимистичный сценарий, а другой – пессимистичный, именуемый наилучший сценарий развития событий из наихудших. И наоборот, наихудший сценарий развития событий из наилучших обращает эти допущения вспять. Для целей данного изложения мы применим этот метод, создав два новых столбца в наборе данных, восполнив значения содержания озона, используя высокие (среднее значение плюс два стандартных отклонения) и низкие (среднее значение минус два стандартных отклонения) оценки за каждый месяц, чтобы проанализировать то, как эти экстремальные значения могут повлиять на результаты. airquality %>% mutate( Ozone_best = coalesce(Ozone, mean(Ozone, na.rm = T) + 2 * sd(Ozone, na.rm = T)), Ozone_worst = coalesce(Ozone, mean(Ozone, na.rm = T) 2 * sd(Ozone, na.rm = T)), .by = Month ) %>% summarize( Ozone_best = round(mean(Ozone_best), 0), Ozone = round(mean(Ozone, na.rm = T), 0), Ozone_worst = round(mean(Ozone_worst), 0), .by = Month ) #> #> #> #> #> #> 1 2 3 4 5 Month Ozone_best Ozone Ozone_worst 5 29 24 19 6 55 29 4 7 69 59 49 8 75 60 45 9 33 31 30
80  Восполнение пропущенных данных 5.2.4. Множественные восполнения Восполнять пропущенные данные лучше, чем их удалять, потому что вместо потери данных они сохраняются! Однако для этого есть свой метод [18]. Множественное восполнение – это статистический метод, который все чаще находит применение с момента его появления в начале 1970-х годов. Указанный метод основан на симуляции и сконструирован для решения проб­лемы пропущенных данных в научных исследованиях. Процесс мно­ жест­венного восполнения состоит из трех главных этапов. 1. Этап восполнения: на этом начальном этапе в наборе данных выявляются пропущенные значения и заменяются набором правдоподобных значений, создавая несколько завершенных наборов данных. Указанные правдоподобные значения, или «восполнения», генерируются на основе выбранной модели восполнения. В целях уменьшения вариабельности выборки в процессе восполнения нередко предпочтительнее генерировать как минимум пять наборов данных. Как показывает опыт, за количество итераций неплохо брать процент пропущенных данных. 2. Этап полного анализа (оценивания) данных: после создания восполненных наборов данных требуемый анализ выполняется обособ­ ленно для каждого набора данных. Например, если на этапе восполнения было сгенерировано пять наборов данных, то будет проведено пять обособленных анализов. 3. Этап сведéния: результаты, полученные в результате каждого анализа полных данных, затем сводятся в единый результат множественного восполнения. Считается, что каждый результат анализа имеет одинаковый статистический вес, поэтому нет необходимости в проведении взвешенного метаанализа. Крайне важно обеспечить совместимость между моделью восполнения и моделью анализа, или чтобы модель восполнения была более общей, чем модель анализа. Это означает, что модель восполнения должна включать больше независимых ковариат, чем модель анализа. Например, если модель анализа включает существенные взаимодействия, то модель восполнения тоже должна их включать. И точно так же, если модель анализа использует преобразованную версию переменной, то модель восполнения должна использовать ту же трансформанту. Примечание 5.3. Важно отметить, что при множественных восполнениях предполагается, что пропущенные данные пропущены случайным образом (MAR). При принятии решения рекомендуется ответить на следующие ниже вопросы. Если вы ответили утвердительно на любой из них, то используйте только наблюдаемые данные. Вместе с тем обсудите и сообщите о количестве пропущенных данных и их ограничениях. Кроме того, рассмотрите возмож-
Работа с пропущенными данными  81 ность включения в свой отчет результатов анализа наилучшего сценария из наихудших и наихудшего сценария из наилучших. 1. Допустимо ли игнорировать пропущенные данные (менее 5 %)? Если да, то в данном случае пропущенные данные незначительны. 2. Является ли значительная доля пропущенных данных (более 40 %) существенной? Если да, то пропущенные данные являются существенными, когда доля превышает этот порог. 3. Пропущены ли данные только в зависимой переменной? Если да, то пропущены только значения зависимой переменной. 4. Правдоподобно ли допущение о полной случайности пропуска данных (MCAR)? Если да, то данные пропущены совершенно случайным об­разом. 5. Правдоподобно ли допущение о неслучайности пропуска данных (MNAR)? Если да, то данные пропущены не случайным образом. Если вы ответите на все эти вопросы отрицательно, то рассмотрите возможность использования множественного восполнения пропущенных данных. 5.2.4.1. Многопеременное восполнение с помощью цепных уравнений Пакет mice на языке R является мощным инструментом обработки пропущенных данных с помощью множественных восполнений. В нем используется алгоритм многопеременного восполнения с помощью цепных уравнений (multivariate imputation by chained equations, аббр. MICE), который создает множественные восполнения (замещающие значения) для многопеременных пропущенных данных. В основе алгоритма лежит идея трактовки каждой переменной, у которой пропущены значения, как зависимой переменной в регрессии, а остальных – как независимых (предсказателей). Об алгоритме MICE можно узнать больше из работ Бюрена и Гроотхейса-Аудсхорна [9]. В алгоритме MICE в отношении пропущенных данных принято допущение о случайности пропуска данных (MAR). Давайте сначала установим и загрузим пакет mice: install.packages("mice") library(mice) Функция mice() поддерживает несколько методов восполнения пропущенных данных. Выбор метода зависит от характера переменных. Вот несколько наиболее часто используемых методов:   "pmm": сопоставление c предсказанным средним значением (predictive mean matching); данный метод широко используется с числовыми данными;   "cart": классификационные и регрессионные деревья; данный метод подходит как для категориальных, так и для непрерывных данных;   "lasso.norm": линейная регрессия с использованием лассо-регуляризации; последняя находит широкое применение в линейных моделях.
82  Восполнение пропущенных данных После восполнения каждый набор данных может быть проанализирован независимо. Давайте выполним некоторые из этих восполнений! Функция mice::complete задействуется для создания полностью восполненного набора данных из объекта mice с указанным методом импутации method и printFlag = FALSE, используемым для предотвращения вывода результатов на консоль. Наконец, $Ozone извлекает столбец. # Определить вспомогательную функцию для восполнения данных Ozone, используя mice mice_impute_ozone <- function(data, method) { mice::complete(mice(data, method = method, print = FALSE))$Ozone } set.seed(1) airquality %>% mutate( Ozone = Ozone, imp_pmm = mice_impute_ozone(., "pmm"), imp_pmm2 = mice_impute_ozone(., "pmm"), imp_cart = mice_impute_ozone(., "cart"), imp_cart2 = mice_impute_ozone(., "cart"), imp_lasso = mice_impute_ozone(., "lasso.norm"), imp_lasso2 = mice_impute_ozone(., "lasso.norm"), .keep = "used" # Оставить только те переменные, которые ) %>% # используются при вызове mutate head_na() #> #> #> #> #> #> 1 2 3 4 5 imp_pmm imp_pmm2 imp_cart imp_cart2 imp_lasso imp_lasso2 20 24 19 16 15.557613 39.24990 6 8 4 1 -16.446412 -25.03575 1 18 34 37 4.801063 -32.22336 23 46 20 36 60.099795 59.77815 39 20 13 12 58.936793 78.69958 Обратите внимание, что повторное выполнение одного и того же описания приводит к другому результату. Такая вариация происходит из-за того, что алгоритмы вводят случайность, которая ведет к неопределенности при вычислении (вместо окончательного восстановленного значения, равного 20, точнее будет ожидать диапазон, например, от 18 до 22). Для того чтобы учесть это и присущую алгоритмам неопределенность, в функции mice() можно задействовать опцию генерации нескольких наборов данных (m=#), чтобы выполнить несколько восполнений пропущенных данных: # Выполнить множественное восполнение imp <- mice(airquality, m = 5, # Количество генерируемых полных наборов данных method = "pmm", # Конкретизирует метод восполнения seed = 1337, # Задать начальное значение для воспроизводимости print = FALSE) # Не печатать историю в консоли
Краткий итог  83 Теперь можно выполнить подгонку линейно-регрессионной модели и подыто­жить объединенные результаты из пяти восполненных наборов данных: # Выполнить подгонку линейной модели на каждом восполненном наборе данных fit <- with(imp, lm(Ozone ~ Solar.R + Wind + Temp + Month)) # Свести воедино результаты этих моделей pool <- pool(fit) summary(pool) #> #> #> #> #> #> term estimate std.error statistic 1 (Intercept) -46.32721776 23.36571710 -1.982700 2 Solar.R 0.04150937 0.02376728 1.746492 3 Wind -3.64264096 0.67015975 -5.435482 4 Temp 1.79526496 0.26398251 6.800697 5 Month -3.13075952 1.58426819 -1.976155 df 51.61341 56.84813 40.01848 90.87476 55.32748 p.value 5.273519e-02 8.612689e-02 2.926986e-06 1.072586e-09 5.313157e-02 Также можно воспользоваться пакетом gtsummary, служащим для создания сводной таблицы, о чем будет рассказано в разделе «Создание таблиц». Здесь функция tbl_regression выполняет автоматическое сведение результатов. library(gtsummary) tbl_regression(fit) Characteristic Solar.R Wind Temp Month Beta 0,04 −3.6 1.8 −3.1 95 % CI −0.01, 0.09 −5.0, −2.3 1.3, 2.3 −6.3, 0.04 p-Value 0.086 <0.001 <0.001 0.053 Восполнение пропущенных данных является ценным инструментом обработки ситуаций, когда в наборах данных пропущены значения, но его следует использовать разумно и на основе глубокого понимания данных и целей анализа. Ответственное восполнение обеспечивает, что любые допущения, принятые в ходе процесса, будут соответствовать методу генерации данных, приводя к более надежному и содержательному анализу данных. 5.3. Краткий итог В этой главе было подробно рассмотрено использование восполнения пропущенных данных как метода устранения пропущенных значений в статистическом анализе, обследованы различные типы пропущенных данных и рассмотрено несколько стратегий управления ими. В данной главе были
84  Восполнение пропущенных данных освещены основные инструменты языка R, служащие для этой цели, и обследован ряд методов восполнения. В частности, в центре внимания была ответственная практика восполнения с целью обеспечения достоверности анализа данных. В следующей части книги ваше внимание будет переключено на методы воспроизводимых исследований. 5.3.1. Таблица методов восполнения пропущенных данных Следующая ниже таблица позволяет сравнить различия в результатах, полученных с помощью каждого метода восполнения. Обратите внимание на возможное значительное различие в результатах восполнения в зависимости от выбранного метода! mice_impute_ozone <- function(data, method) { mice::complete(mice(data, method = method, print = FALSE))$Ozone } set.seed(1) airquality %>% mutate( # Восполнить фиксированным значением (в данном случае 0) imp_fixed = coalesce(Ozone, 0), Ozone_missing = is.na(Ozone), # Восполнить средним значением imp_mean = coalesce(Ozone, round(mean(Ozone, na.rm = TRUE), 2)), imp_fill = Ozone, # Восполнить медианой imp_median = coalesce(Ozone, median(Ozone, na.rm = TRUE)), imp_forest = missForest(.)$ximp$Ozone, imp_lm = ifelse(is.na(Ozone), predicted_values, Ozone), imp_knn = airquality_knn$Ozone, imp_pmm = mice_impute_ozone(., "pmm"), imp_cart = mice_impute_ozone(., "cart"), imp_lasso = mice_impute_ozone(., "lasso.norm"), .keep = "used" ) %>% fill(imp_fill, .direction = "down") %>% filter(is.na(Ozone)) %>% select(-Ozone) %>% mutate(across(everything(), ~ round(., 1))) %>% gt::gt()
Краткий итог  85 Таблица 5.1. Результаты различных методов восполнения, за исключением методов Ozone_missing и imp_fixed, которые не вошли в таблицу imp_mean imp_fill imp_median imp_forest imp_lm imp_knn imp_pmm imp_cart imp_lasso 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 42,1 16 11 32 40 32 18 32 32 39 77 89 71 35 35 21 16 16 64 20 20 20 20 13 23 32 29 35 59 61 89 65 23 31 84 20 45 14 4 108 63 23 64 82 16 84 84 84 71 37 59 49 63 37 45 20 44 45 9 39 32 40 61 71 49 79 59 21 14 108 18 13 8 34 20 21 19 49 47 32 73 63 97 36 59 59 48 16 16 37 65 9 65 22 73 39 20 44 44 28 89 44 22 21 61 12 48,6 −5,0 2,2 37,2 35,8 25,8 66,9 67,2 44,6 81,9 38,2 70,9 34,6 48,3 72,8 47,1 45,6 42,8 63,0 55,7 3,8 29,2 28,3 30,7 49,4 28,2 63,0 24,2 48,2 81,2 53,0 9,9 40,3 78,1 13,3 8 32 32 37 37 37 37 37 37 29 39 39 23 23 13 13 13 13 13 13 13 13 13 13 32 85 27 16 16 110 110 65 9 73 30 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 22,8 12,8 24,8 36,6 27,5 20,0 47,7 65,4 28,7 63,7 68,9 75,0 33,2 32,2 40,4 59,3 54,8 49,1 23,7 30,6 17,5 33,9 17,2 47,2 41,1 28,9 66,7 41,3 37,9 89,0 45,4 23,8 22,2 76,8 19,3 35,4 −16,2 1,7 51,6 40,7 4,2 56,8 62,7 34,9 75,6 73,8 77,4 44,0 49,5 56,0 65,1 57,3 60,0 46,9 52,5 31,6 43,7 23,7 63,6 43,9 51,5 56,1 55,0 53,0 71,3 46,3 30,5 31,1 74,6 25,4
ЧАСТЬ II Воспроизводимые научные изыскания
Глава 6 Воспроизводимое исследование Когда вы пишете научную статью, вы расширяете границы знаний. Хорошее исследование не просто открывает что-то новое; оно делает это систематическим и воспроизводимым способом. Ведь вы бы не поверили исследованию, которое невозможно подтвердить, не правда? Невоспроизводимые единичные случаи не имеют для науки никакой значимости [25]. Опрос ученых, проведенный журналом Nature в 2016 году [3], показал, что 70 % исследователей не смогли повторить эксперименты других ученых, а более 50 % не смогли воспроизвести свои собственные эксперименты. В связи с этим возникает вопрос о том, как представлять информацию таким образом, чтобы другие могли подтверждать результаты опубликованного исследования. Мы используем принципы воспроизводимого исследования. В справочнике «Путь Тьюринга» [10] воспроизводимое исследование определяется как процесс, в котором работа может быть независимо переделана с использованием данных и исходного кода изначального коллектива. Эта концепция отличается от повторяемости, которая предусматривает проведение одинакового анализа на разных наборах данных, и надежности (робастности), которая подразумевает применение разных методов анализа к одинаковому набору данных; исследователи нередко утверждают, что их результаты надежны, ссылаясь на альтернативные спецификации моделей. Наконец, золотым стандартом считается обобщаемость, которая достигается в ситуациях, когда разные данные и методы производят сходные результаты. В дополнение к этому можно различать разные типы воспроизводимости [28]:   вычислительная воспроизводимость фокусируется на деталях исходного кода, программного обеспечения, реализации и операционной системы. Например, использование разных версий языка и операционных систем может приводить к разным результатам;
88  Воспроизводимое исследование   эмпирическая воспроизводимость подчеркивает важность информации о невычислительных научных экспериментах. Она охватывает такие аспекты, как вопросы опроса, процедуры взятия выборок, исполнение экспериментов и многие другие;   статистическая воспроизводимость предусматривает тонкости статис­ тических тестов и модельных параметров. Решающую роль в получении исходов играет то, как модель специфицируется, используются стандартные ошибки, применяются пакеты и параметры, определенные как явно, так и неявно (предустановленные значения параметров для пакетов). Данные Анализ Одинаковый Разный Одинаковый Воспроизводимый Повторяемый Разный Надежный Обобщаемый Рис. 6.1  Понимание воспроизводимых исследований согласно справочнику «Путь Тьюринга» Повторяемость, хотя и важна, бывает затруднена такими ограничениями, как время, ресурсы и возможности. Поэтому часто целесообразнее сосредоточиваться на воспроизводимости – обеспечении того, чтобы аналитические данные и исходный код были доступны другим пользователям с целью подтверждения находок. Воспроизводимость – это не просто цель, а стандарт, в особенности для научных изысканий, которые по своей сути трудно повторить. Для обеспечения минимальной воспроизводимости необходимо предоставить использованные в анализе аналитические данные. Хотя доступ как к сырым данным, так и к исходному коду обработки желателен, это не всегда является обязательным условием для воспроизведения анализа. Важно, чтобы также был предоставлен аналитический исходный код, включая спецификации модели, используемой для получения результатов. Не менее важно предоставить исчерпывающую документацию1 как для данных, так и для исходного кода, чтобы пролить свет на набор данных и объяснить назначение и функцио­ нальность исходного кода. Наконец, эта информация должна быть легко доступна через общие каналы распространения, такие как GitHub, что обеспечит легкий доступ и использование широким исследовательским сообществом. 6.1. Грамотное программирование Важной технологией для построения воспроизводимого исследования является грамотное программирование. Оно объединяет фрагменты текста и исходного кода, создавая гармоничное сочетание понятных человеку объяснений 1 http://documentation.qmd/.
Грамотное программирование  89 и машинно-исполняемого кода. Исходный код загружает данные, генерирует графики и выполняет модели, тогда как текст предоставляет контекст и предлагает толкование результатов. Такой подход позволяет исследователям создавать документы, которые будут понятны как человеку, так и машине. Одной из самых ранних реализаций грамотного программирования был инструмент Sweave, который совмещал LaTeX и R для документирования и программирования. С тех пор указанная область эволюционировала, например, с появлением разметки RMarkdown, блокнотов Jupyter и упрощенной разметки Python Markdown. Последней разработкой в этой области является современный инструмент для создания динамических документов на основе упрощенной разметки под названием Quarto, который предлагает исследователям комплексное решение для создания прозрачных, воспроизводимых и хорошо документированных результатов исследований. Собранные данные Исходный код обработки Аналитические данные Аналитический исходный код Результаты вычислений Исходный код презентации Рисунки Таблицы Сводки Текст Статья Рис. 6.2  Поток грамотного программирования На рис. 6.2 показана схема рабочего потока грамотного программирования, которая помогает понять, что такое воспроизводимое исследование; теперь давайте рассмотрим различные шаги, которые необходимо предпринять. В качестве примера мы применим рабочий поток к гипотетическому проекту по анализу удовлетворенности покупателей. Цель этого проекта – оценить удовлетворенность покупателей с помощью опроса и подготовить отчет с изложением результатов. 1. Собранные данные: вы собрали ответы, полученные в ходе опроса об удовлетворенности покупателей, их предпочтениях и отзывах. Не забудьте сохранить сырые данные для справки.
90  Воспроизводимое исследование 2. Исходный код обработки: разработайте отдельный исходный код для очистки собранных данных, устранения нестыковок, пропущенных значений и нерелевантных записей. Задокументируйте принятые допущения и процессы, избегая категоричных методов, которые могут повлиять на результаты. 3. Аналитические данные: очищенные данные служат основой для анализа, предоставляя точную информацию. Поделитесь этими очищенными данными с заинтересованными сторонами. 4. Аналитический исходный код: примените различные аналитические методы получения осмысленных сведений из аналитических данных, выявления трендов, закономерностей и корреляций. Подробно задокументируйте этот аналитический исходный код. 5. Результаты вычислений: сгенерируйте результаты вычислений, выделяя ключевые находки, такие как средние баллы удовлетворенности, распространенные жалобы и сегменты покупателей. 6. Исходный код презентации: разработайте исходный код для создания визуализаций, диаграмм и графиков, которые эффективно передают результаты опроса заинтересованным сторонам и другим аналитикам: – рисунки: визуальные презентации иллюстрируют тренды и распределение, например метрику лояльности покупателей (Net Promoter) во временной динамике и распределение по сегментам покупателей; – таблицы: используйте таблицы для демонстрации фрагментов данных, включая сводки и визуальную информацию; – сводки: подытожьте важные выводы из таблиц, такие как регрессионные и пятичисловые сводки1. 7. Текст: включите описательный текст, чтобы обеспечить контекст и пояснения к визуальным и табличным компонентам. 8. Статья: поделитесь своими выводами, используя рисунки, таблицы и сводки, которые вы создали с помощью своего исходного кода, и расскажите историю с помощью текстового повествования. Следует помнить, что это лишь упрощенная презентация, а реальные проекты могут включать в себя более изощренные этапы и соображения. 6.2. Краткий итог Будем надеяться, что теперь вы понимаете важность воспроизводимых исследований в научных изысканиях и осознаете трудности, связанные с повторяемостью экспериментов. Надеемся, что вы также стремитесь освоить грамотное программирование, о котором мы расскажем в следующей части. Но сначала давайте обследуем основополагающий аспект надежности исследований – концепцию воспроизводимой среды. 1 Минимум, первый квартиль (Q1), медиана (Q2), третий квартиль (Q3), максимум.
Глава 7 Воспроизводимая среда Воспроизводимые среды имеют решающее значение при разработке современного программного обеспечения, поскольку они гарантируют стабильные результаты независимо от системы или времени исполнения. Эти среды являются ключом к достижению надежности, масштабируемости и безотказности, которые необходимы для бесперебойной совместной работы и эффективной диагностики проблем и обслуживания. В современных сложных программных проектах, обремененных запутанными зависимостями, необходимость в воспроизводимости неоспорима. Изменения или обновления в этих зависимостях могут приводить к отказам в исходном коде или проблемам с переносимостью. В данном контексте полезно ознакомиться с управлением версиями пакетов. Номера версий, такие как 1.2.3, указывают на масштаб и характер обновлений. Мажорные версии (1.x.x) содержат важные изменения, минорные версии (x.2.x) добавляют обратно совместимые функциональные способности, а патч-версии (x.x.3) исправляют ошибки, поддерживая обратную совместимость. Термин «ад зависимостей», который часто встречается в проектах машинного обучения, относится к проблеме управления конфликтующими, ненадежными или несовместимыми зависимостями. Воспроизводимые среды, в которых регистрируются все кодовые зависимости, предлагают безотказное решение этой проблемы. Обновления пакетов, в которые вносятся критически важные изменения, могут существенно нарушать работу кодовой базы. Этот риск можно снижать, старательно регистрируя конкретные версии пакетов и следя за заметками о выпусках и новостями. Пакет renv (от англ. reproducible environment, то есть воспроизводимая среда) на языке R решает эти проблемы, создавая изолированные среды, ориентированные на конкретные проекты. Он эффективно управляет зависимостями пакетов R, документируя точные версии, необходимые для вашего проекта, и восстанавливая их по мере необходимости. За счет этого обеспечивается состыкованность версий пакетов в разных сеансах R и проектах.
92  Воспроизводимая среда 7.1. Пакет renv Пакет renv значительно улучшает изоляцию, переносимость и воспроизводимость проектов R. Он обеспечивает изоляцию, назначая каждому проекту отдельную библиотеку, предотвращая конфликты между пакетами в разных проектах. Он обеспечивает переносимость, облегчая миграцию проектов между различными компьютерами и платформами, тем самым упрощая установку пакетов. Более того, пакет renv обеспечивает воспроизводимость, регистрируя точные версии пакетов, что имеет решающее значение для поддержания состыкованности и надежности в разных средах и позволяет точно воспроизводить настройки проекта. 7.1.1. Рабочий поток init() Cистемная библиотека snapshot() Библиотека проекта Кеш install() пакета update() renv status() Файл renv.lock restore() Ваш компьютер CRAN/ GitHub/... Интернет Рис. 7.1  Изображение принятого в пакете renv рабочего потока из документации по пакету Интеграция пакета renv в существующий проект или запуск нового элементарна. Надо инициировать среду с помощью функции renv::init(), которая создает файл renv.lock и обнаруживает зависимости вашего исходного кода. Для фиксации текущего состояния зависимостей используется функция renv::snapshot(). Примечание 7.1. Пакет renv автоматически исключает файлы, перечисленные в вашем файле .gitignore. Для установки конкретных пакетов в рамках проекта, управляемого пакетом renv, следует использовать функцию renv::install(), которая устанавливает пакеты и регистрирует их в файле renv.lock вашего проекта. Когда для ваших пакетов будут доступны обновления, функция renv::update() поможет без проблем применить эти обновления, а также обновит файл renv.lock, чтобы он соответствовал новым версиям.
Вычислительные среды  93 Для быстрой проверки статуса зависимостей вашего проекта функция renv::status() предоставляет мгновенный обзор любых расхождений между текущей средой проекта и зарегистрированным состоянием в файле renv. lock. При коллективном использовании исходного кода или его выполнении в новой среде функция renv::restore() переустанавливает пакеты из файла renv.lock. Реализация воспроизводимых сред в ваших проектах дает массу преимуществ. По мере того как вы будете лучше знакомиться с пакетом renv, ознакомьтесь с его документацией, чтобы узнать больше о его способностях и дополнительных функциональностях. Ценность настройки воспроизводимой среды становится совершенно очевидной после того, как вы потратите несколько часов на устранение ошибок, вызванных обновлениями пакетов. 7.2. Вычислительные среды В области исследований компьютерных вычислений простого отслеживания версий пакетов бывает недостаточно. На результаты анализа могут сущест­ венно влиять такие факторы, как версия операционной системы и взаимодействие между внешними пакетами. Для тех, кто стремится улучшить свои методы обеспечения воспроизводимости, полезным следующим шагом является обследование возможностей виртуальных машин и контейнеризации. Виртуальные машины, по сути, симулированные компьютеры, предлагают универсальное решение. Они позволяют создавать «виртуальный» компьютер, выбирая его операционную систему и другие атрибуты, и работать с ним так же, как с любым обычным приложением. Внутри этой виртуальной среды находится рабочий стол, файловая система, стандартные библиотеки программного обеспечения и многое другое, и все это работает так же, как на физическом компьютере. Исследователи могут настроить виртуальную машину, провести свои исследования в этой контролируемой среде, а затем сохранить ее состояние – вместе с файлами, настройками и результатами. Это сохраненное состояние затем может быть распространено в виде комплексного, полнофункционального проекта. Если вы хотите узнать больше о виртуальных машинах, то перейдите на веб-сайт VirtualBox1. Контейнеры имеют много общих преимуществ с виртуальными машинами, но отличаются своим подходом и эффективностью. В то время как виртуальные машины копируют всю операционную систему и программное обеспечение в комплекте (независимо от того, требуется ли оно для проекта или нет), контейнеры более избирательны. Они включают в свой состав только конкретное программное обеспечение и файлы, необходимые для проекта, что делает их значительно более облегченными и эффективными, 1 См. https://www.virtualbox.com/.
94  Воспроизводимая среда чем виртуальные машины. Более подробную информацию о контейнерах можно найти на веб-сайте Docker1. 7.3. Краткий итог Выработка умения ориентироваться в тонкостях создания воспроизводимых аналитических расчетов достигается со временем и поначалу может быстро стать непростым делом. Важно оценить необходимый уровень технических знаний и вероятную техническую квалификацию ваших сотрудников. Если нет острой необходимости в таких продвинутых решениях, как виртуальные машины, контейнеры или декларативные операционные системы, то, возможно, будет более практичным не углубляться в эти области. Многие сотрудники могут быть недостаточно технически подкованы, чтобы с комфортом ориентироваться в этих более сложных решениях. Начните с выработки привычки использовать такие инструменты, как пакет renv. Как только вы и ваш коллектив освоитесь с подобными основополагающими методами, вы сможете постепенно обследовать возможности применения более продвинутых вариантов, таких как контейнеры и виртуальные машины. В следующих двух главах вы кратко познакомитесь с командной оболочкой, а затем воспользуетесь ею для изучения методов управления версиями с помощью Git и GitHub. 1 См. https://www.docker.com/.
Глава 8 Введение в командную оболочку Командная оболочка, также именуемая интерфейсом командной строки (command-line interface, аббр. CLI), или терминалом, представляет собой инструмент для работы с файлами, выполнения программ и управления системными настройками. В отличие от графического интерфейса пользователя (graphical user interface, аббр. GUI), где пользователи взаимодействуют с визуальными элементами, в командной оболочке взаимодействуют с компьютером, набирая текстовые команды. Несмотря на его пугающий внешний вид, понимание командной оболочки может открыть почти волшебные возможности. В командной оболочке рабочей областью является текущий каталог или рабочая директория. Между каталогами перемещаются с помощью команды cd (change directory). Например, команда cd Documents перемещает пользователя в каталог Documents в текущем каталоге. Каталоги в командной оболочке имеют как относительный, так и абсолютный пути. Относительный путь к каталогу – это его имя. Например, в команде cd Documents используется относительный путь к документам. Абсолютные пути указывают полный путь от корневого каталога к соответствующему каталогу. Например, в команде cd/home/username/Documents используется абсолютный путь /home/username/Documents. 8.1. Освоение основных команд Команды формируют ядро взаимодействий с командной оболочкой, выступая в качестве инструкций, которые мы набираем в терминале для выполнения определенных заданий, таких как манипулирование файлами и навигация по каталогам.   pwd: команда «распечатать рабочий каталог» (print working directory) показывает текущий каталог.
96  Введение в командную оболочку   cd: команда «сменить каталог» (change directory) позволяет перемещаться между каталогами. Применение команды cd с разными аргументами позволяет перемещаться более эффективно: – cd ..: дает возможность перейти на один каталог выше; – cd /: позволяет перейти в корневой каталог; – cd ~: дает возможность перейти в домашний каталог; – cd .: ссылается на текущий каталог.   ls: команда «вывести список» (list) показывает файлы и каталоги в текущем каталоге.   touch [имя_файла]: создает новый файл.   cat [имя_файла]: показывает содержимое файла.   cp [источник] [адресат]: команда «скопировать» (copy) дублирует файлы или каталоги.   mv [источник] [адресат]: команда «переместить» (move) переименовывает или перемещает файлы.   rm [имя_файла]: команда «удалить» (remove) удаляет файлы.   rm -r [каталог]: команда «удалить рекурсивно» (remove recursively) удаляет каталоги и их содержимое, включая все файлы и подкаталоги.   mkdir [имя_каталога]: команда «создать каталог» (make directory) создает новый каталог.   rmdir [имя_каталога]: команда «удалить каталог» (remove directory) удаляет пустой каталог. Имена каталогов можно выстраивать в цепочку косой чертой / для навигации. Это относится как к абсолютным, так и к относительным путям. Например, команда cd /home/username/projects/my_project позволяет перейти к папке my_project, указав абсолютный путь. С другой стороны, команда cd projects/my_project позволяет перейти в то же местоположение, используя относительный путь. Если требуется перейти в родительский каталог, а затем в дочерний, то можно применить команду cd ../sibling_directory. Эта команда означает «подняться на один уровень вверх, а затем спуститься в папку sibling_directory». Эти базовые команды являются отправной точкой для взаимодействия с командной оболочкой. По мере ознакомления вы будете осваивать более сложные команды и сочетания, создавая мощные функциональные средства. Помните, что не надо стесняться разведывать и экспериментировать. Командная оболочка является тем инструментом, который можно и нужно использовать в своих интересах! 8.2. Начало работы с Nano nano – это простой и удобный текстовый редактор, широко используемый в Unix-подобных операционных системах. Он отлично подходит для начина-
Начало работы с Nano  97 ющих благодаря простому интерфейсу и командам. Для того чтобы открыть файл в редакторе nano, наберите команду nano, а затем имя файла: nano filename.txt Если файл не существует, то редактор nano создаст новый файл с таким именем. После открытия файла вы сможете перемещаться по нему с помощью клавиш со стрелками. Вы можете использовать сочетания клавиш Ctrl+A для перехода к началу строки, Ctrl+E для перехода к концу строки, Ctrl+Y для перехода на предыдущую страницу и Ctrl+V для перехода на следующую страницу. Редактировать текст в nano так же просто, как и печатать. Для вырезки текущей строки текста используется команда Ctrl+K. Если требуется вставить вырезанный текст, то используется команда Ctrl+U. По завершении редактирования можно сохранить изменения, применив команду Ctrl+O, пос­ле чего nano предложит подтвердить или изменить имя файла. Для выхода используется команда Ctrl+X. Если вы внесли изменения, то nano спросит, нужно ли их сохранить. Если вы застряли или вам нужно узнать больше команд, то с помощью команды Ctrl+G можно открыть меню справки nano. Выше были рассмотрены основные команды управления файлами и каталогами, а также команды работы с текстом. Настоятельно рекомендую использовать свой терминал для повседневной работы. Хотя поначалу работа в нем, возможно, покажется медленной и неприятной, со временем вы к нему привыкнете и будете использовать его с меньшим нежеланием. По мере того как вы будете чувствовать себя все комфортнее, продолжите обследовать другие инструменты командной оболочки, такие как fzf для нечеткого поиска файлов, grep для поиска и замены текста и ffmpeg для взаимодействия с видео- и аудиофайлами. В следующей главе будут рассмотрены методы управления версиями с помощью Git и GitHub.
Глава 9 Контроль версий с помощью Git и GitHub Представьте себе, что вы неустанно работаете над дипломной работой. Вы потратили несколько дней на обдумывание идей, написание истории, программирование, пересмотр и добавление визуализаций. После нескольких часов доработки все почти идеально – до тех пор, пока ваш надежнейший ноутбук не решит самоуничтожиться. Если бы вы сохранили свою работу в интернете, то вам не пришлось бы искать последнюю версию, отправленную по электронной почте, или переписывать ее с печатной копии с комментариями вашего консультанта на полях. Или, что еще хуже, начинать с нуля! Не останавливаясь, вы начинаете хранить все на Google Диске, думая, что теперь вы в безопасности. Вы беретесь за большой проект по написанию исходного кода, создавая впечатляющую модель с элегантным интерфейсом. Но когда вы пытаетесь привести в порядок свой запутанный исходный код, все приложение выходит из строя и превращается в полный ошибок кошмар. Если бы только существовал простой способ вернуться к предыдущей версии или поработать над новыми изменениями, не нарушая работу главной кодовой базы! Если что-то из этого покажется вам знакомым, то я понимаю вашу боль. Но если нет, еще не поздно предотвратить подобные катастрофы с помощью системы контроля версий! Представьте себе систему контроля версий в виде окончательной папки с надписями «финальная_версия», «финальная_версия2.0» и «финальная_версия1.2.5». Она отслеживает все изменения, которые вы вносите в документы, исходный код и файлы данных, действуя как машина времени, которая возвращает вас к любой точке истории вашего проекта. С ее помощью вы можете восстановить любую предыдущую версию своей работы. Звучит волшебно, не правда? Вот как работает система контроля версий. 1. Моментальные снимки: при каждом сохранении своей работы система контроля версий делает моментальный снимок, сохраняя эту конкретную версию с комментарием о том, что вы сделали.
Система контроля версий Git и веб-платформа GitHub  99 2. Ветвление: хотите попробовать новую смелую идею, но опасаетесь, что она может не сработать? Нет проблем! С помощью системы контроля версий можно создать отдельную «ветку» и поэкспериментировать, не затрагивая главную версию. Если ваша идея сработает, то вы сможете «влить» изменения обратно в главную ветку. Если нет, то просто удалить экспериментальную ветку и сделать вид, что этого никогда не происходило. 3. Совместная работа: работа в коллективе? Управление версиями упрощает совместную работу. Все члены коллектива могут работать над свои­ ми отдельными частями проекта, а затем «объединять» все изменения в единое целое, заменяя переписку по электронной почте на «финальная_версия_3_пересмотренная_исправленная_ФИНАЛЬНАЯ_ревизия». 4. Резервное копирование: система контроля версий также действует как система резервного копирования, обеспечивая безопасное хранение работы в дистанционно расположенном месте. Так что даже если ваш компьютер решит от вас отказаться, ваш проект останется защищенным и доступным. 9.1. Система контроля версий Git и веб-платформа GitHub Git – это широко используемая система контроля версий, которая эффективно управляет проектами различного масштаба и сложности и распространяет их. Git незаменима для разработчиков, ученых, аналитиков и писателей, поскольку она отлично отслеживает изменения, способствует совместной работе и обработке исходного кода. Доступ к Git, как и к интерфейсу командной оболочки, осуществляется через терминал. Веб-платформа GitHub расширяет функциональность системы Git, предлагая удобный интерфейс по управлению проектами и совместной работе. Дополнительные функциональные средства включают отслеживание проб­ лем, инспекцию исходного кода и инструменты управления проектами. Веб-платформа GitHub также служит социальной сетью для разработчиков, облегчая обмен результатами работы, поиск проектов и использование материалов с открытым исходным кодом. Примечание 9.1. Разница между системой Git и веб-платформой GitHub такая же, как и разница между морским судном и морским хабом. Поначалу использовать систему контроля версий Git и веб-платформу GitHub, возможно, будет немного сложно и запутанно, в особенности если вам нужна лишь небольшая часть функциональности. Цель данной главы – дать вам возможность освоиться с основами, чтобы вы могли хранить, обновлять, сотрудничать и делиться своими работами на веб-платформе GitHub.
100  Контроль версий с помощью Git и GitHub Существует множество руководств по установке системы Git на компьютер и ее подключению к среде RStudio. Я поделюсь своей версией. Я рекомендую использовать руководство от Hester [16] «Happy Git и GitHub для пользователя R» в качестве ориентира для других ваших приключений с Git. После того как вы пройдете весь процесс установки, вы, возможно, захотите его подключить к среде RStudio, но это необязательно. Поскольку запомнить команды и связать с действиями и состоянием вашего репозитория, возможно, будет трудно, вам следует установить клиент Git, который будет получать сводку истории последних коммитов и ветвей, а также графический интерфейс, упрощающий операции с Git. Попробуйте приложения GitHub Destop или GitKraken. Примечание 9.2. Находясь в репозитории GitHub, нажмите «.», чтобы запус­ тить веб-версию редактора VSCode. 9.2. Основы Теперь давайте кратко пробежимся по основам системы контроля версий Git и веб-платформы GitHub. Цель изложения состоит в том, чтобы познакомить с ключевыми понятиями и продемонстрировать, что начать работу с системой контроля версий довольно просто. Репозитории на GitHub – это хранилища проектов, в которых можно управлять файлами, организовывать их и работать с ними коллективно, одновременно отслеживая изменения с помощью системы контроля версий Git. Для того чтобы создать репозиторий, начните с подхода «сперва Github» или «сперва локально». Другими словами, в первом случае вы сначала инициируете репозиторий на GitHub, а затем клонируете его на свой компьютер, а во втором – сначала пишете исходный код, а потом подключаете свой репозиторий к GitHub. Обычно я использую подход «сперва локально», так как часто начинаю проект и только потом принимаю решение о целесообразности вывода его в онлайн. С помощью приложения GitHub Destop добавить репозиторий очень просто. Для этого достаточно выбрать File → New Repository (Файл → Новый репозиторий). При этом существует два типа репозиториев: приватные и публичные. Этот статус можно изменить в настройках своего репозитория. Допустим, вы выполнили некоторую работу и хотите ее сохранить. Вы хотите закоммититься, то есть зафиксировать результаты работы в репозитории. Для этого надо выбрать все файлы, которые нужно добавить в коммит git add file.md, или добавить все файлы с помощью команды git add ., а затем исполнить команду git commit -m "сообщение";. Сообщение необходимо добавить в коммит для того, чтобы не забыть, какие изменения были внесены. Все это можно сделать в своем клиенте и даже в среде RStudio нажатием нескольких кнопок. Тем не менее советую освоиться с командной оболочкой. Итак, вы внесли изменения, но они еще не доступны онлайн; они только зарегист­ рированы, благодаря чему вы сможете их загрузить, если у вас что-то не получится. У вас может быть несколько коммитов, поэтому можно добавлять
Основы  101 все больше и больше изменений, прежде чем вы будете готовы поделиться своей работой со всем миром. Как только вы будете готовы, надо исполнить команду git push, чтобы закачать все изменения в свой репозиторий GitHub, и все они там появятся! Рабочий каталог add Область подготовки изменений для включения pull commit Локальный репозиторий Git push Дистанционный репозиторий Git, например GitHub Рис. 9.1  Команды git add, commit, push, pull Что делать, если вы хотите скачать версию с GitHub, потому что, скажем, хотите работать на другом компьютере? Команда git pull совмещает получение обновлений из дистанционного репозитория и их вливание в вашу локальную ветку. Она также позволяет синхронизировать локальную ветку с последними изменениями из дистанционного репозитория, обеспечивая актуальность проекта и облегчая сотрудничество с другими участниками. Примечание 9.3. Применение команд add, commit, push и pull позволяет избегать около 80 % распространенных проблем! Но что, если ваш партнер обновит версию на GitHub, пока вы работаете? Теперь вам нужно каким-то образом вставить изменения в свою работу. Для этого сначала нужно применить команду pull, и если нет конфликтов, то есть вы не меняли одну и ту же строку, то она автоматически объединит обе версии. Но что, если вы работали над документом и возникли конфликты? Вам нужно их урегулировать. Урегулирование конфликта слияния (или объединения) в системе Git преду­ сматривает выявление конфликтующих изменений и ручное принятие решения о том, какие изменения сохранить или модифицировать внутри файла с конфликтом. Внутри файла это будет выглядеть следующим образом: #> #> #> #> #> <<<<<<< HEAD Это строка в вашей текущей ветке ======== Это строка в ветке, которую вы вливаете. >>>>>>> <branch-name>
102  Контроль версий с помощью Git и GitHub В целях урегулирования конфликта надо отредактировать файл, чтобы оставить желаемые изменения и удалить маркеры конфликта. Вы можете сохранить изменения из текущей ветки или ветки, которую вы вливаете, или вообще создать новую строку: #> Это новая урегулированная строка. Сохраните изменения в файле и подготовьте изменения для включения в файл с помощью команды git add. Закоммитите урегулированный конф­ ликт слияния с помощью команды git commit -m "Урегулирован конфликт слияния в файле". Вспомните мою попытку привести исходный код в порядок, которая привела к сбою (вторая история). В целях предотвращения аналогичной ситуации следует использовать ветки Git. Ветки позволяют работать с несколькими функциональностями или исправлениями, не затрагивая главную кодовую базу. После того как они будут завершены и протестированы, надо влить ветвь обратно в главную ветвь. При разветвлении создается персональная копия репозитория под вашей учетной записью, а при клонировании – локальная копия на вашем компьютере. Разветвление полезно в проектах с открытым исходным кодом, позволяя участникам вносить изменения, не затрагивая изначальный проект. После тестирования надо передать запрос на включение изменений, чтобы предложить обновления в изначальном репозитории. Запрос на включение изменений предлагает влить изменения из одной ветви в другую, обычно из разветвленного репозитория в изначальный репозиторий. Это облегчает обсуждение, инспекцию и совместную работу, позволяя техническим сопроводителям проекта одобрять, изменять или отклонять предлагаемые изменения. Раздел проблем на GitHub помогает отслеживать ошибки, запросы или обсуждения, связанные с проектом. Они служат централизованным форумом для общения, распределения задач и мониторинга прогресса, обеспечивая эффективное управление проектом и своевременное решение каких-либо затруднений. 9.3. Руководство по использованию файла .gitignore Файл .gitignore сообщает системе Git о том, какие файлы не следует отслеживать или игнорировать перед выполнением коммита. Его применение особенно широко распространено в коллективных проектах, в которых разные разработчики имеют свои собственные конфигурации, настройки
Руководство по использованию файла .gitignore  103 и интегрированные среды разработки (IDE), или в ситуациях, когда имеются временные файлы, которые генерируются при исполнении программы. Давайте пройдемся по процедуре создания файла .gitignore и управления им. Для того чтобы создать файл .gitignore, нужно перейти в корневой каталог проекта и создать новый файл с именем .gitignore. Это можно сделать непосредственно в редакторе исходного кода или в терминале: touch .gitignore 9.3.1. Перечисление файлов, которые следует игнорировать Примечание 9.4. В файле .gitignore следует всегда указывать свои логины, пароли, секреты и другую конфиденциальную информацию! Замена учетных данных и удаление старых из репозитория после их публикации могут вызвать проблемы. Откройте файл .gitignore в текстовом редакторе и укажите файлы, каталоги или шаблоны имен файлов, которые следует исключить. Каждая новая строка должна содержать новое правило.   Для того чтобы игнорировать каталог, достаточно добавить имя каталога, например node_modules/.   Для того чтобы игнорировать файл, надо добавить полное имя файла, например debug.log.   Для того чтобы игнорировать тип файла, следует использовать *., за которым следует расширение файла, например *.log.   Комментарии можно добавлять, начиная строку с символа #. Ниже приведен пример файла .gitignore: # Игнорировать каталог node_modules node_modules/ # Игнорировать все .log files *.log # Игнорировать secret.json file secret.json Для файлов, которые вы хотели бы игнорировать глобально, во всех проектах, можно создать глобальный файл .gitignore: git config --global core.excludesfile ''~/.gitignore'' Теперь вы можете определить все правила в файле, и они будут применяться во всех репозиториях.
104  Контроль версий с помощью Git и GitHub 9.3.2. Файл .gitignore в других программах Хотя файл.gitignore был создан в системе управления версиями Git и чаще всего ассоциируется с ней, концепция определения игнорируемых файлов и каталогов была принята другими программными средствами. Среди них различные интегрированные среды разработки (IDE), текстовые редакторы и даже некоторые операционные системы. Многие из этих инструментов поддерживают использование файла .gitignore в том, что касается исключения файлов и каталогов, и всегда лучше ознакомиться с документацией к конкретным инструментам, чтобы узнать, как они справляются с игнорированием файлов. Для большинства языков программирования и популярных программных инструментов сообществом разработчиков с открытым исходным кодом были созданы и поддерживаются стандартные файлы .gitignore. На GitHub есть репозиторий этих файлов. Их можно использовать в качестве отправной точки для своих проектов. 9.4. Краткий итог Примечание 9.5. Не удаляйте папку .git/, так как она содержит всю историю! В этой главе были рассмотрены основы контроля версий с помощью системы контроля версий Git и веб-платформы GitHub, причем особое внимание было уделено отслеживанию изменений, управлению проектами и совместной работе. В ней были рассмотрены основные команды Git, использование репозиториев, ветвление, конфликты слияния и важность файла .gitignore. Будем надеяться, что вы убедились в важности контроля версий и видите, что он не слишком сложен. Рекомендую вам воспользоваться ресурсами, на которые даны ссылки, или найти свои собственные, чтобы узнать больше! В следующей главе будет затронут вопрос о том, как оформлять свой исходный код.
Глава 10 Стилизация и статический анализ исходного кода Погружаясь в программирование, вы вполне можете пренебречь такими эстетическими аспектами, как правильные отступы или разрывы строк, что, однако, придаст исходному коду менее удобочитаемый вид и сделает более подверженным ошибкам. Важно придерживаться определенных правил написания исходного кода, чтобы улучшать удобочитаемость и сводить к минимуму количество ошибок. В этом поможет ознакомление с правилами оформления исходного кода R; по ходу изложения будут представлены пакеты styler и lintr, которые улучшают эстетику исходного кода и обнаруживают потенциальные ошибки. Хороший стиль написания исходного кода, как и правильная пунктуация, значительно улучшает удобочитаемость. Важно помнить, что хотя некоторые рекомендации улучшают удобство в использовании, другие бывают субъективными. Однако их истинная ценность заключается в обеспечении единообразности, что упрощает процесс написания исходного кода. Вы можете задаться вопросом: если вас устраивает ваш стиль написания исходного кода, то зачем использовать эти инструменты? Хотя субъективные преимущества есть, первостепенная причина кроется в том, что они повышают доступность вашего исходного кода и устраняют ненужные стилистические изменения из коммитов в git. Примечание 10.1. Для Mac и Windows символы табуляции обозначаются поразному. Если в исходном коде есть символы табуляции, то в другой операционной системе он может отказать. В целях обеспечения совместимости следует использовать пробелы (ваш редактор может конвертировать символы табуляции в пробелы).
106  Стилизация и статический анализ исходного кода 10.1. Руководство tidyverse по стилю Давайте пройдемся по нескольким базовым рекомендациям, которые можно начать применять немедленно. Эти рекомендации взяты из руководства tidyverse по стилю, которое можно прочитать не более чем за 20 минут. Настоятельно рекомендуется ознакомиться с ним по адресу https://style.tidyverse.org. 10.1.1. Пробелы и отступы Рекомендуется использовать 2-пробельные (или 4-пробельные) отступы, чтобы иллюстрировать структуру и иерархию в исходном коде. Содержимое функций также должно соответствовать этому правилу. Для функций с конвейерными разделителями строку следует начинать после каждого нового разделителя и делать соответствующие отступы, чтобы обеспечивать ясность и удобочитаемость. Правильно for (i in 1:10) { print(i) } iris %>% group_by(Species) %>% summarize_if (is.numeric, mean) %>% ungroup() %>% gather(measure, value, -Species) %>% arrange(value) Неправильно for (i in 1:10){ print(i)} iris %>% group_by(Species) %>% summarize_all(mean) %>% ungroup %>% gather(measure, value, -Species) %>% arrange(value) 10.1.2. Правила именования В языке R есть уникальная операция <-, используемая для присваивания значений переменным. Ее всегда следует использовать в качестве оператора присваивания вместо оператора =. Одной из самых сложных сторон во всем программировании является назначение имен переменным. В языке R принято использовать змеиный_стиль именования вместо горбатогоСтиля или чего-либо еще. В качестве имен переменных рекомендуется применять су­ществительные, при этом не следует стесняться делать имена немного
Руководство tidyverse по стилю  107 длиннее. Нужно стремиться к идеальному балансу, при котором исходный код будет удобочитаемым, но в то же время лаконичным. Для функций рекомендуется всегда использовать глаголы, поскольку они выполняют действия. Правильно average_height <- 1.70 add_row() permute() Неправильно averageHeight = 1.70 AverageHeight = 1.70 row_adder() permutation() 10.1.3. Фигурные скобки Фигурные скобки {} рекомендуется использовать в своем исходном коде R стратегически, с целью повышения удобочитаемости, группируя команды, которые работают в паре. В инструкциях if-else следует помещать открывающую фигурную скобку { в той же строке, что и условие, а закрывающую фигурную скобку } в новой строке. Убедитесь, что инструкция else находится в одной строке с закрывающей фигурной скобкой в предыдущей секции if. Такая конфигурация облегчает выявление обособленных блоков исходного кода. Правильно if (condition) { action1() } else { action2() } Неправильно if (condition) { action1() } else { action2() } 10.1.4. Комментарии Комментирование исходного кода экономит время и предотвращает путаницу в дальнейшем. Несмотря на то что исходный код должен быть понятен сам
108  Стилизация и статический анализ исходного кода по себе, комментарии предоставляют бесценный контекст для обоснования исходного кода и помогают документировать ключевые выводы и решения при анализе данных. Думайте о том, как при обращении к нему в будущем не почувствовать себя сбитым с толку. Для написания комментария используется символ # и пробел. При этом следует соблюдать регистр предложений и ставить точку в конце только в том случае, если ваш комментарий состоит из нескольких предложений. Каждую строку комментария следует начинать с символа # и пробела. Если вы обнаружите, что для объяснения исходного кода требуется много комментариев, то подумайте о том, чтобы его доработать на предмет большей ясности. Исходный код, который нуждается в слишком большом количестве комментариев, пожалуй, лучше подойдет для многословной платформы, такой как Quarto. Правильно # Вычислить среднюю высоту – эта метрика используется для нормализации Неправильно # Мы находим среднюю высоту #Мы суммируем все высоты и делим на количество высот 10.1.5. Длинные функции Следует стараться, чтобы в строке исходного кода было не более 80 символов. Она хорошо вписывается в стандартную печатную страницу при использовании удобочитаемого размера шрифта. Если вы обнаружите, что исходный код превышает это ограничение, то следует принять это как подсказку к тому, чтобы поместить часть исходного кода в отдельную функцию. Что касается вызовов функций, которые выходят за рамки одной строки, то Нужно отводить отдельные строки для имени функции, каждого ее аргумента и закрывающей круглой скобки. Эта практика улучшает удобочитаемость и позволяет вносить изменения в будущем. Правильно long_function_name <- function(argument1, argument2, argument3, argument4) { # тело функции } Неправильно long_function_name <- function(argument1, argument2, argument3, argument4) { # тело функции }
Статический анализатор исходного кода  109 К счастью, вам не придется зацикливаться на форматировании, поскольку существуют инструменты автоматизации этого процесса. Пакеты styler и lintr на языке R могут применять эти рекомендации автоматически, что придает им практическую значимость при изучении этих правил. 10.2. Форматировщик Форматировщик – это инструмент, предназначенный для обработки исходного кода и обеспечения единообразного форматирования таких элементов, как точки с запятой, пробелы и другие детали, которые не влияют на функциональность исходного кода. Как и во многих других языках, в языке R тоже есть свой собственный форматировщик! Пакет styler форматирует исходный код в соответствии с руководством tidyverse по стилю. Его легко установить с помощью команды install.packages("styler"). После установки вы найдете новую функцию в меню Addins (Дополнения) в верхней части окна RStudio. Для быстрого доступа к функции Style Selection (Выбор стиля) рекомендуется задать сочетание клавиш, например Command+Shift+a. До iris %>% ggplot(aes(Sepal.Length, Sepal.Width)) + geom_point() После iris %>% ggplot(aes(Sepal.Length, Sepal.Width)) + geom_point() 10.3. Статический анализатор исходного кода Линтер, или инструмент статического анализа исходного кода, служит для выявления потенциальных ошибок, обеспечения соблюдения стандартов программирования и улучшения качества исходного кода. Он помогает разработчикам, автоматически делая проверки на наличие распространенных ошибок, таких как опечатки или неправильное использование средств языка, и обеспечивая соответствие кода лучшим образцам практики. В языке R есть свой собственный статический анализатор исходного кода, пакет lintr, который выявляет проблемы со стилем, программированием и синтаксисом. Вот краткое описание этих трех компонентов.
110  Стилизация и статический анализ исходного кода 1. Проблемы со стилем: lintr проверяет, соответствует ли исходный код рекомендациям по стилю, например тем, которые определены в руководстве tidyverse по стилю. Он проверяет правильность отступов, длину строк, использование пробелов вокруг операторов и многое другое. 2. Проблемы с программированием: lintr ищет потенциальные ошибки программирования и неоптимальный исходный код, такие как использование неопределенных переменных, использование = вместо <- для присваиваний и наличие комментариев TODO. 3. Проблемы с синтаксисом: lintr выполняет проверки на наличие любых синтаксических ошибок в исходном коде, таких как пропущенные круглые скобки или неправильное использование ключевых слов языка. В определенных средах разработки, таких как RStudio, статический анализ исходного кода с помощью пакета lintr может выполняться автоматически либо вызываться вручную из консоли R с помощью инструкции lintr::lint(имя_файла = "path/bad.R"). Это во многом помогает улучшать качество исходного кода, удобочитаемость и техническую сопроводимость. Форматировщики и статические анализаторы исходного кода, возможно, выглядят похоже, но у них разные функции. Форматировщик работает быст­ рее и приводит в порядок исходный код с целью улучшения удобочитаемости, тогда как статический анализатор работает немного медленнее, но необходим для обнаружения и предотвращения ошибок в исходном коде. Таким образом, форматировщик придает исходному коду причесанный вид, а статический анализатор поддерживает его в безошибочном состоянии. 10.4. Краткий итог В этой главе подчеркивается важность надлежащей практики написания исходного кода на языке R, основанной на руководстве tidyverse по стилю. В ней также представлены пакеты styler и lintr, которые помогают форматировать исходный код с целью улучшения удобочитаемости и обнаружения потенциальных ошибок и дефектов. В следующей главе вы узнаете, как придавать модульность своему исходному коду.
Глава 11 Модульный исходный код Работа с одним файлом проходит гладко, пока вы не наберете пару сотен строк. Затем поиск ошибок, внесение правок и просто понимание своего местоположения в файле становятся довольно проблематичными. Выручают добавление комментариев, создание оглавления или использование поиска для навигации по файлу, но это всего лишь временные решения. Они становятся совершенно неэффективными при коллективном использовании исходного кода с другими пользователями. Дополнительные проблемы возникают в ситуациях, когда приходится загружать несколько библиотек, что приводит к конфликтам в пространстве имен, или когда все разумные имена переменных и функций заняты, и в итоге получается что-то вроде very_important_variable_2_winz. 11.1. Реиспользование функций Перенос всех повторяющихся действий в функции – это один из самых прос­ тых шагов по улучшению исходного кода и упрощению его технического сопровождения и понимания. Хотя может возникнуть соблазн разбить исходный код на небольшие функции для каждой крошечной задачи, например создать отдельные функции для вычисления среднего значения, стандартного отклонения, t-балла и p-значения, практика подсказывает, что нужно прежде всего сосредоточиться на цели функции. Если вы обнаружите, что необходимо использовать часть более крупной функции повторно, то рекомендуется выделить ее в обособленную функцию. Абстрагируя свой исходный код в функции, вы получаете преимущества его реиспользования и улучшенной модульности. Вдобавок абстрагирование исходного кода в функции помогает разбивать глубоко вложенный исходный код на более управляемые части, что облегчает его чтение и понимание.
112  Модульный исходный код Цель состоит в том, чтобы найти баланс между созданием функций, которые служат определенной цели, и избеганием чрезмерного количества мелких функций. Подход на основе предназначений обеспечивает эффективную передачу каждой функцией предписанной ей цели, что улучшает удобочитаемость исходного кода. Абстрагируя свой исходный код и организуя его в виде целенаправленных функций, вы получите легче понимаемый и сопровождаемый исходный код. Если вы выполняете что-то больше, чем несколько раз, то это, скорее всего, относится к функции. Предположим, что нужно рассчитать среднее значение и стандартное отклонение у нескольких наборов данных. Для этого можно было бы использовать пакетные функции mean и sd на каждом из них по отдельности, но давайте определим единую функцию. Заключение исходного кода в функции имеет свои преимущества для реиспользования и абстрагирования, к примеру создав функцию, которая вычисляет среднее значение и стандартное отклонение числового вектора. calculate_stats <- function(data) { mean_value <- mean(data) sd_value <- sd(data) return(list(mean = mean_value, sd = sd_value)) } 11.2. Разбивка исходного кода Как только объем файла превысит сотню строк, имеет смысл разделить его на несколько файлов в зависимости от функции. Это значительно улучшит удобочитаемость исходного кода. Для запуска скриптов из заданного файла можно использовать функцию source(). Например, сначала выполняется скрипт load_data, который сохраняет загруженные данные, а затем выполняются скрипты data_preprocessing и data_visualization. Вдобавок скрипты можно загрузить в ту же локальную среду с параметром local = TRUE. data_loading.r load_data <- function(file_path) { # Исходный код загрузки данных из файла } data_processing.r preprocess_data <- function(data) { # Исходный код предобработки данных } data_visualization.r visualize_data <- function(data) { # Исходный код визуализации данных }
Разбивка исходного кода  113 main.r source(data_loading.r, local = TRUE) source(data_preprocessing.r, local = TRUE) source(data_visualization.r, local = TRUE) Теперь давайте рассмотрим простое применение функции source() при работе с несколькими файлами. В примере показан процесс с использованием фрагментов, размещенных в отдельных файлах: name.csv содержит одну запись "Dima"; load_data.r загружает данные из csv; add_title.r определяет функцию add_title, объединяющую имя и обращение; say_hi.r определяет функцию say_hi, добавляя "Hi" к имени; а main.r задействует команду вызова, чтобы загрузить эти модули, и демонстрирует их использование в последовательности связанных в цепочку операций. В конечном счете исходный код выдает результат "Hi Mr. Dima", акцентируя внимание на том, как source интегрирует функции из нескольких файлов. name.csv Dima # CSV с одной записью load_data.r # Прочитать `name.csv` и получить имя my_name <- read.csv("name.csv", header = FALSE) add_title.r source("load_data.r") # add_title конкатенирует обращение и имя add_title <- function(name, title) { return(paste(title, name)) } say_hi.r # say_hi конкатенирует имя и "Hi" say_hi <- function(name) { return(paste("Hi", name)) } main.r # main.r запускает say_hi и add_title source("say_hi.r") source("add_title.r") title <- "Mr." add_title(myName, title) |> say_hi() |> print() #> [1] "Hi Mr. Dima"
114  Модульный исходный код 1.3. Упаковка исходного кода в модули Система экспорта-импорта на основе пакета box в языке R позволяет конвертировать обычные файлы R в реиспользуемые модули, упрощая коллективное использование исходного кода без его организации в пакеты. Функции можно экспортировать, помещая директиву #' @export перед именем функции. Например: say_hi.r #' @export say_hi <- function(name) { return(paste("Hi", name)) } Функция box::use() служит универсальным объявлением импорта, заменяющим традиционные библиотечные функции или функции require в базовом R. Она обеспечивает более четкую и гибкую загрузку пакетов или модулей, сокращая количество ошибок. Например, вместо загрузки всей библиотеки с помощью команды library(ggplot2) можно использовать команду box::use(ggplot2[...]). Она дает возможность загружать конкретную функцию, позволяя избегать конфликтов имен и улучшая отслеживаемость происхождения функции. Она также позволяет использовать псевдонимы, назначая другое имя пакету или его функциям при импорте: load_data.r # Загрузить функцию read.csv из utils и переименовать ее в read box::use( utils[read = read.csv] ) #' @export my_name <- read("name.csv", header = FALSE) add_title.r #' @export add_title <- function(name, title) { return(paste(title, name)) } Эти модули могут храниться в центральном хранилище или в рамках отдельных проектов и могут быть импортированы и применены с помощью функции box::use(), например: main.r box::use( # Загрузить файлы ./say_hi, ./add_title, ./load_data[my_name] )
Краткий итог  115 box::use( stringr[str_split_1] # Загрузить фукцию из пакета stringr ) title <- "Mr." # Обратиться к функции и переменной, используя нотацию "модуль$переменная" add_title$add_title(my_name, title) |> say_hi$say_hi() |> # str_split_1 разбивает строковый литерал по пробелу на вектор символов str_split_1(pattern = " ") #> [1] "Hi" "Mr." "Dima" "!" Модули в рамках пакета box имеют сходство с пакетами R, но их проще создавать и использовать. Помимо этого, они предлагают такие функциональные особенности, как иерархическая вложенность. box – это замечательный пакет, который очень поможет в крупных проектах. Он также является частью платформы блестящего фреймворка rhino. В нем содержится гораздо больше информации, поэтому обязательно ознакомьтесь с официальной документацией. 11.4. Краткий итог В этой главе было рассмотрено управление сложными скриптами на языке R посредством их модульной организации в функции и отдельные файлы. Были затронуты вопросы использования функций для повторяющихся задач, разделение длинных скриптов на более мелкие целевые файлы и использование системы экспорта-импорта на основе пакета box для создания реиспользуемых модулей. Эти стратегии улучшают удобочитаемость исходного кода и удобство его сопровождения, а также предотвращают конфликты пространства имен, что делает их полезными для управления крупными проектами R. Следующая далее часть книги будет посвящена процессу исследования, начиная с обзора научных публикаций.
ЧАСТЬ III Обзор научных публикаций и написание статьи
Глава 12 Обзор научных публикаций Каждое увлекательное изыскательское приключение начинается с обзора научных публикаций. Обзор научных публикаций – необходимый этап в любом исследовании, позволяющий выявлять пробелы в знаниях и формулировать исследовательский вопрос. В этом разделе представлены мощные инструменты, которые ускорят процесс составления обзора научных публикаций, начиная с первоначального разведывания темы и заканчивая составлением заключительных заметок. 12.1. Поиск Как правило, розыск научных публикаций начинается с обращения к профессору или специалисту в данной области, который укажет правильное направление и даже поддержит на ранних этапах, что в конечном итоге сэкономит время и усилия. Отличной отправной точкой является изучение обзорных статей, поскольку в них дается всесторонний обзор последних разработок, обобщаются основные выводы и выявляются существующие пробелы в данной области. Кроме того, если в этой теме вы являетесь новичком, подумайте о том, чтобы почитать учебное пособие, дабы получить базовые знания. Продолжите работу обследованием баз данных, доступных по подписке вашего университета, таких как Scopus1 и Web of Science2. Указанные базы данных сопровождаются специальными коллективами экспертов-рецензентов, которые обеспечивают высокое качество размещаемых в них статей. Вдобавок не стоит забывать и о своей университетской библиотеке, так как 1 2 См. https://www.scopus.com/home.uri. См. https://mjl.clarivate.com/search-results.
118  Обзор научных публикаций она может бесплатно предоставлять доступ к дорогостоящим базам данных и материалам для чтения. Примечание 12.1. Следует остерегаться хищнических журналов! Несмотря на их кажущуюся легальность, эти журналы, как известно, публикуют любые материалы за плату. Если вы не уверены, просмотрите веб-сайт журнала и обратитесь к репозиторию хищнических издателей и журналов Список Джеффри Билла (Jeffrey Beall)1. После ознакомления с этими ресурсами расширьте поиск с помощью поисковой службы Google Академия2 (Google Scholar), где представлена обширная коллекция статей. Однако следует иметь в виду, что ответственность за проверку качества работы лежит на вас. Что касается книжных ресурсов, то подумайте о посещении личного веб-сайта автора, где могут быть предложены бесплатные главы или даже полная книга. Современный способ ускорения процесса составления обзора научных публикаций предусматривает использование таких инструментов, как Elicit3, чтобы получить первые несколько статей и их резюме с обзором тем. Такие инструменты, как Research Rabbit4 и Lit Maps5, создают сети из имеющихся у вас статей и позволяют находить статьи, которые располагаются рядом в этой сети, помогая отыскивать менее известные, но актуальные статьи. Лично меня много раз спасал от необходимости искать новые статьи именно ИИ-инструмент Research Rabbit. Наконец, для оптимальной организации исследований можно воспользоваться инструментом Arc Browser6. Он облегчает создание структурированных пространств для каждого проекта, обеспечивая эффективную навигацию по папкам, содержащим все ссылки и заметки. 12.2. Управление справочными материалами Собирая статьи, где вы их храните? В менеджере справочных материалов! Наличие менеджеров справочных материалов в сфере научных исследований обусловлено необходимостью эффективно организовывать и управлять научными источниками. Среди них менеджер библиографических данных Zotero7 выделяется как наиболее всеобъемлющий инструмент. Это бесплат1 2 3 4 5 6 7 См. https://beallslist.net/. См. https://scholar.google.com/. См. https://elicit.org/. См. https://www.researchrabbit.ai/. См. https://app.litmaps.com/. См. https://arc.net/. См. https://www.zotero.org/.
Чтение статей  119 ное кросс-платформенное приложение с открытым исходным кодом, оснащенное широким спектром расширений. Zotero позволяет добавлять статьи, используя коды DOI, ISBN, ссылки и файлы, читать PDF-файлы внутри приложения, а также поддерживать общий онлайновый репозиторий в облаке, добавлять теги, связанные со ссылками на справочные материалы, вставлять заметки и аннотировать, с дополнительным удобством экспорта всей этой информации в предпочитаемое приложение для ведения заметок. Его совместимость с многочисленными программами для написания текс­ тов упрощает процесс цитирования в различных средах. Расширьте свой опыт, используя веб-расширение менеджера Zotero1 для организации удобного сбора справочной информации из интернета. Для еще большей функ­ циональности установите плагин Betterbibtex 2, который улучшает работу Zotero, генерируя точные ключи цитирования и облегчая автоматический экспорт вашей библиотеки в BibTeX. Для всего, что вам может понадобиться, есть необходимое расширение. При первой настройке менеджера Zotero также настоятельно рекомендуется неукоснительно следовать инструкциям. 12.3. Чтение статей Подготовив подборку научных публикаций, теперь важно перелопатить статьи, расставив приоритеты в зависимости от их качества, значимости и актуальности. Возможно, это противоречит здравому смыслу, но научные статьи необязательно читать в том порядке, в котором они представлены. Начните с краткого ознакомления с названием, аннотацией, выводами и цифрами каждой статьи, чтобы оценить ее значимость. Этот предварительный просмотр поможет наиболее подходящим статьям занять первое место в вашей виртуальной стопке, и не бойтесь отбрасывать те, которые не соответствуют вашим потребностям. Такой подход позволит понять главные выводы и следствия, прежде чем переходить к более подробным техническим аспектам. Иногда бывает трудно сохранять концентрацию и темп, в особенности при работе с длинными или сложными текстами, поэтому используйте приложение для преобразования текста в речь Speechify3, которое озвучивает статьи. Этот инструмент не только помогает поддерживать темп чтения, но и улучшает понимание текста. В стратегическом плане общепринято одновременно использовать приложение Speechify и менеджер Zotero, чтобы иметь возможность слушать статью, делая структурированные заметки в Zotero. Для того чтобы еще больше упростить процесс, попробуйте интеллектуальный чат-бот DocAnalyzer.ai4, вопросно-ответный инструмент Zotero QA 1 2 3 4 См. https://www.zotero.org/download/connectors. См. https://retorque.re/zotero-better-bibtex/. См. https://speechify.com/. См. https://docanalyzer.ai/.
120  Обзор научных публикаций на Hugging Face1 или помощника исследователя ARIA2, которые были разработаны тем же автором, для того чтобы задавать вопросы о библиотеке Zotero. В дополнение к этому рассмотрите возможность загрузки PDF-файлов в ChatGPT, чтобы задавать вопросы и просматривать коллекции специализированных GPT-моделей. 12.4. Ведение заметок Эффективное ведение заметок – важная часть процесса составления обзора научных публикаций, и подход к ним должен соответствовать масштабу вашего проекта. Делая заметки, следует стараться делать их краткими, то есть они должны быть прямолинейными и целенаправленными. Если вы хотите превратить их в связную историю, не забудьте включить ссылки на источники. Что касается самого текста, то для коротких и средних статей может оказаться достаточным простой метод, например делать заметки в Google Документы. Позже эти заметки могут быть доработаны и структурированы в связное эссе. Однако в случае более масштабных исследовательских работ решающее значение имеет систематический подход к составлению заметок и их организации. Рассмотрите возможность использования таких инструментов управления заметками, как Obsidian3. Он отлично подходит для создания взаимосвязанных сетей идей с использованием файлов упрощенной разметки Markdown и позволяет более организованно и взаимосвязанно понимать результаты ваших исследований. В качестве альтернативы инструмент управления проектами Notion4 предлагает динамичную платформу для организации заметок, задач и баз данных, удовлетворяющую различные потребности организации. Эти платформы можно дополнительно совершенствовать за счет интеграции с возможностями менеджера Zotero по экспорту данных, что позволяет легко переносить справочные материалы и заметки в выбранное приложение для ведения заметок. В дополнение к этим инструментам значительно упростить процесс составления обзора научных публикаций могут технологические решения с использованием искусственного интеллекта, такие как ChatGPT5. ChatGPT отлично справляется с резюмированием текста, улучшением стиля написания и преобразованием текста в структурированные таблицы в формате Markdown. Это особенно полезно для переложения потока мыслей в отточенный академический язык. С его помощью также можно объяснять визу1 2 3 4 5 См. https://huggingface.co/spaces/lifan0127/zotero-qa. См. https://github.com/lifan0127/ai-research-assistant. См. https://obsidian.md/. См. https://www.notion.so/. См. https://openai.com/blog/chatgpt.
Краткий итог  121 альные элементы, такие как таблицы, графики и диаграммы. Кроме того, он помогает при планировании научных работ и предоставлении критических отзывов. Используя указанные выше передовые инструменты, вы избежите замедления работы и обеспечите более эффективный процесс составления обзора научных публикаций. Однако не стоит слишком на них полагаться в выполнении своей работы; рекомендуется всегда проверять и редактировать результаты. Это всего лишь инструменты, которые не заменяют ваш опыт. 12.5. Краткий итог Вот мой типичный рабочий процесс: 1. Поговорить с экспертом. 2. Прочитать обзорные статьи, статьи для начинающих и учебники. 3. Использовать инструмент Elicit для получения первоначальных текстов. 4. Выполнить поиск в поисковой службе Google Академия. 5. Поместить все данные в менеджер библиографических данных Zotero. 6. Расширить информацию с помощью инструмента Research Rabbit. 7. Просмотреть и отфильтровать статьи. 8. Прочитать с помощью приложения Speechify. 9. Сделать заметки в файле Markdown, цитируя работы, хранящиеся в Zotero. 10. Преобразовать заметки в черновик с помощью ChatGPT. 11. Написать в системе Quarto и уйти на следующую итерацию. 12. Получить отзывы с помощью инструмента Trackdown. 13. Экспортировать в LaTeX и выполнить набор содержимого на онлайновой платформе Overleaf1. В этой главе было рассмотрено несколько полезных ресурсов, которые значительно упростят процесс составления обзора научных публикаций и помогут систематизировать все полученные знания. В следующей главе будут охвачены технологии и инструменты написания статей! 1 См. в следующей главе.
Глава 13 Написание научной статьи После составления всестороннего обзора существующих научных публикаций у вас должна уже сформироваться концепция своей будущей статьи. В этой главе рассматриваются различные технологии, с которыми вы, вероятно, столкнетесь в поисках эффективного текстового редактора, и дается обзор базового синтаксиса системы для создания документов и отчетов Quarto. 13.1. WYSIWYG Редакторы в стиле WYSIWYG (от англ. What You See Is What You Get, то есть «Что видите, то и получаете») являются программами, которые позволяют создавать и редактировать содержимое визуально, не прибегая к программированию. Это означает, что по мере создания содержимого можно видеть, как оно будет выглядеть. Они очень полезны для людей, не имеющих опыта работы с языками программирования или языками разметки. Примеры редакторов WYSIWYG, с которыми вы, возможно, уже знакомы, включают Google Документы и Microsoft Word. Научившись ориентироваться в этих широко используемых инструментах, вы приобретете ценные навыки, такие как форматирование и написание текстов. Плюс после непродолжительного времени их использования вы начнете ценить простоту и эффективность языков разметки. Настоятельно рекомендуется освоить эти инструменты, так как приобретенные навыки работы с ними легко переносимы на другие подобные редакторы. Кроме того, вложенные усилия в их освоение будут неоценимы еще и потому, что ваши коллеги, скорее всего, тоже будут ими пользоваться. Для начала рекомендуется ознакомиться с серией для сертификации Специалист в Microsoft Office (Microsoft Office Specialist, аббр. MOS); например, на онлайновой платформе для обучения LinkedIn Learning есть отличные варианты учебных пособий. Указанные пособия предназначены для тех, кто готовится к сдаче экзаменов по MOS, и охватывают широкий спектр функцио­нальности
Языки разметки  123 Microsoft Word, Excel и PowerPoint. Настоятельно рекомендуется ознакомиться с этими учебными пособиями, даже если вы не планируете сдавать экзамены. Это отличный ресурс для развития ваших навыков и совершенствования владения этими необходимыми инструментами! 13.2. Языки разметки Языки разметки – это наборы кодов, которые обеспечивают структуру и форматирование документов, таких как веб-страницы, электронные книги и научные статьи. В отличие от редакторов WYSIWYG, которые позволяют пользователям создавать содержимое наглядно, языки разметки нуждаются в использовании специальных тегов или кодов, сообщающих о том, как содержимое должно выводиться на экран. Указанные теги задают структуру документа, форматирование и другие атрибуты. К числу наиболее часто используемых языков разметки относятся HTML, LaTeX и Markdown. Изучив язык разметки, вы сможете лучше контролировать внешний вид и функциональность своих цифровых документов. Дополнительно к этому языки разметки помогут лучше сосредоточиваться на написании текста, позволяя заготовкам выполнять все форматирование. Обещаю, что после того, как вы переключитесь, пути назад не будет! Ваши задания и веб-страницы всегда будут выглядеть просто великолепно. 13.2.1. HTML Термин «язык разметки» часто ассоциируется с широко распространенным инструментом создания веб-контента HTML (Hypertext Markup Language, то есть языком разметки гипертекста). В HTML используются теги, с помощью которых авторы описывают вывод контента в веб-браузерах. В HTML основополагающими являются такие теги, как <br> для переносов строк и <img> для изображений. Знание языка разметки HTML является ключевым навыком в веб-разработке, обеспечивая основу для индивидуальной настройки веб-страниц и приложений. HTML также часто используется для работы с текстом в графиках. 13.2.2. LaTeX Вы когда-нибудь задумывались о том, почему научные статьи выглядят так красиво или почему все учебники выглядят одинаково? Все они написаны в системе набора текста LaTeX, используемой для академических и научных публикаций. Это язык разметки, который позволяет точно форматировать сложные технические документы. Он также известен своими прекрасными математическими уравнениями. С помощью LaTeX пользователи могут
124  Написание научной статьи создавать профессионально выглядящие документы с высокой степенью индивидуальной настройки и гибкости. Его легко использовать, но трудно освоить. Вводные онлайновые уроки и чат LaTeX помогут получить ответы на большинство вопросов, связанных с LaTeX. Если у вас есть уравнение, которое вы хотите перенести в LaTeX, то для этого подойдет инструмент MathPix1, который конвертирует изображения или скриншоты в код. Среди редакторов LaTeX широкой популярностью пользуется онлайновая платформа OverLeaf2, которая упрощает процесс написания статей и предлагает подробные руководства по любым возникающим вопросам. 13.2.3. Упрощенная разметка Markdown Язык упрощенной разметки Markdown отличается вниманием к деталям и удобным конструктивным исполнением. Это облегченный язык разметки, созданный для генерирования форматированного текста в обычном текстовом редакторе. Его привлекательность заключается в простоте и удобочитаемости в форме исходного кода, что резко контрастирует со сложностью традиционных языков разметки, таких как HTML. Markdown популярен среди разработчиков, писателей и блоггеров из-за своей простоты и адаптивности. Он поддерживает целый ряд элементов, включая ссылки, изображения и другие мультимедийные функции. Благодаря широкой поддержке язык разметки Markdown совместим с многочисленными инструментами и платформами, такими как текстовые редакторы, приложения для ведения заметок и системы управления контентом. Изучение языка упрощенной разметки Markdown позволит эффективно генерировать хорошо структурированный, удобочитаемый контент, не полагаясь на сложные инструменты форматирования или специализированное программное обеспечение. На самом деле эта книга изначально была полностью написана в таком формате. Для работы с языком разметки Markdown рекомендуется приложение MacDown для Mac, Markdown Pad для Windows, StackEdit для онлайнового использования или Typora для тех, кто предпочитает премиальный вариант. 13.2.4. YAML YAML (от англ. Yet Another Markup Language, то есть «Еще один язык разметки») представляет собой понятный пользователю язык сериализации данных, который часто используется для конфигурационных файлов и обмена данными. В нем используются отступы, пары ключ-значение и словари и поддерживаются разные типы данных. Словари используются для организации данных в виде пар ключ-значение с отступом, чтобы указывать 1 2 См. https://mathpix.com/image-to-latex. См. https://www.overleaf.com/.
Quarto  125 иерархию. Ключ представляет собой уникальный идентификатор или имя, а значение – ассоциированные данные или содержимое. YAML легко читать, и на нем легко писать. Он популярен в веб-разработке и конфигурировании программного обеспечения. % Key value pairs title: "Dead Souls" author: "Nikolai Gogol" date: 03/09/1842 % Map chapters: – index.qmd – chapter1.qmd 13.2.5. Pandoc Pandoc (буквально означает «все документы») конвертирует файлы из одного формата разметки в другой. Он служит универсальным инструментом для конвертации файлов между различными форматами разметки, включая HTML, Markdown, LaTeX, PDF и Microsoft Word. Этот служебный программный инструмент позволяет быстро и без проблем конвертировать документы на разных языках без ручного редактирования или переформатирования. Возможности инструмента Pandoc разнообразны: от конвертирования файлов Markdown в HTML для веб-страниц до преобразования документов LaTeX в PDF-файлы для печати. Он также отлично подходит для слияния нескольких документов в один файл и извлечения содержимого конкретных форматов. Его высокая настраиваемость обеспечивает широкий контроль над форматом и внешним видом выходных данных, что делает его одним из основных инструментов для академических и научных публикаций, вебразработки и документирования. Автоматизация конвертации форматов с помощью Pandoc значительно сокращает время и усилия. Несмотря на то что Pandoc является инструментом командной оболочки, он хорошо интегрируется с некоторыми редакторами Markdown, расширяя функциональность упрощенной разметки Markdown за счет таких средств, как таблицы, сноски, цитаты и многое другое. Например, эта книга была написана на языке Markdown, а затем преобразована в форматы HTML и PDF с помощью инструмента Pandoc. 13.3. Quarto Сейчас вам, возможно, интересно, почему вам пришлось прочитать об этих технологиях. Потому что сочетание инструментов Markdown, YAML и Pandoc предоставляет мощный и гибкий инструментарий для создания документов.
126  Написание научной статьи Те, кто знаком с блокнотами Sweave, Rmarkdown или Jupyter, найдут систему для создания документов и отчетов Quarto похожим инструментом. Quarto развивает успех блокнотов Rmarkdown и Jupyter, сочетая самые лучшие возможности языка упрощенной разметки Markdown с новыми функциональными возможностями и устраняя необходимость в дополнительных пакетах. Он предоставляет привлекательные предустановленные параметры форматирования и простую индивидуальную настройку. Если у вас есть опыт написания текстов на Markdown, то использовать Quarto будет очень легко для любой из следующих ниже задач:   создание воспроизводимых документов и отчетов;   генерирование динамического контента с помощью языков Python, R, Julia и инструмента Observable;   создание контента профессионального уровня, такого как статьи, отчеты, презентации, веб-сайты, блоги и книги, в различных форматах, включая HTML, PDF, MS Word, ePub и другие;   разработка с использованием научного языка упрощенной разметки Markdown с формулами, цитатами, перекрестными ссылками, панелями рисунков, выносками, расширенными макетами и многим другим;   разработка интерактивных руководств и блокнотов. 13.3.1. Ваш первый документ Для того чтобы начать применять систему Quarto, не требуется никакого специального программного обеспечения; при желании даже можно использовать текстовый редактор для создания файлов .qmd и командную оболочку для визуализации документа. Однако работа в интегрированной среде разработки (IDE) значительно облегчит жизнь. В качестве нее предпочтительно использовать среду RStudio; в конце концов, Quarto является продуктом компании Posit (ранее RStudio), однако редактор Visual Studio Code тоже работает неплохо. Систему Quarto можно установить из среды Rstudio так же, как и любой другой пакет. Вдобавок следует установить минимальный набор пакетов TinyTeX, необходимых для компиляции документов LaTeX. Оба пакета можно получить, выполнив следующую ниже команду на языке R: install.packages(c("quarto", "tinytex")) Для того чтобы создать проект Quarto, надо перейти в верхнюю панель → File (Файл) → New Project (Новый проект) → Directory (Каталог) → Quarto Project (Проект Quarto) → Create File (Создать файл) → Quarto Document (Документ Quarto) → написать название вашего документа → выбрать нужный формат (по умолчанию используется HTML) → Create (Создать). (Опциональный) заголовок YAML обозначен тремя тире (---) с обеих сторон. О параметрах YAML можно узнать больше на веб-сайте Quarto. Для вывода на экран существует масса полезных опций.
Quarto  127 --title: "Title" author: Nikita Tkachenko date: today format: pdf --- Если вы предпочитаете стиль WYSIWYG, то можете переключиться на визуальный редактор в верхнем левом углу. Вдобавок если поставить галочку Render to Save (Отрисовать для сохранения), то после каждого сохранения будет обновляться новый предпросмотр документа. Теперь пришло время заняться написанием статьи! Примечание 13.1. Для затравки заголовок H1 в yaml может быть определен как "Title" и как # Title. Синтаксис языка Markdown Результат # Заголовок 1 Глава # Заголовок 2 # Заголовок 3 # Заголовок 4 # Заголовок 5 # Заголовок 6 *косой шрифт* **полужирный шрифт** надстрочный шрифт^2^ <https://nber.org> [NBER]<https://nber.org> ![Caption](golden_gte.pdf) неупорядоченный список + элемент – подэлемент – подподэлемент упорядоченный список 1. элемент I. подэлемент i. подподэлемент Внутристрочные матформулы: $E = mc^{2}$ Документные матформулы: $$E = mc^{2}$$ Раздел Подраздел Подподраздел Параграф Подпараграф наклонный шрифт полужирный шрифт надстрочный шрифт2 https://nber.org NBER неупорядоченный список • элемент – подэлемент · подподэлемент упорядоченный список 1. элемент I. подэлемент i. подподэлемент Внутристрочные матформулы: E = mc2 Документные матформулы: E = mc2
128  Написание научной статьи Что касается написания обычного текста, то в этом нет ничего особенного; просто пишете как обычно. Если требуется добавить разрыв строки, то достаточно добавить пустую строку между абзацами; в противном случае блок текста будет продолжаться как один и тот же текст. Примечание 13.2. Для удобного доступа к параметрам синтаксиса рекомендуется использовать визуальный режим! Используйте `...` для добавления внутристрочного исходного кода: print(hi, friend). Используйте ``` для разграничения блоков исходного кода: ``` print(hi, friend) ``` Создавать таблицы на языке Markdown не так уж и сложно. Наиболее часто используется конвейерная таблица. Она позволяет просматривать выравнивание и названия с помощью символа :. Таблицы довольно быстро могут усложниться; если вы когда-нибудь столкнетесь с трудностями, то следует обратиться к документации Quarto по таблицам. | Default | Left | Middle | Right | |---------|:-----|:------:|--------:| | Hola | Pitt | 3.141 | Nile | | Bonjour | Li | 2.718 | Amazon | | Salut | Roth | 4.123 | Yangtze | : Table Demonstration Таблица 13.1. Демонстрация таблицы Default Hola Bonjour Salut Left Pitt Li Roth Middle 3.141 2.718 4.123 Right Nile Amazon Yangtze Если вы когда-нибудь почувствуете себя запутавшимся или столкнетесь с трудностями при форматировании, то следует воспользоваться визуальным редактором. Он предоставляет знакомый интерфейс и особенно полезен для создания и предварительного просмотра таблиц. Для настройки параметров, например количества опций списка, достаточно кликнуть по значку круга с многоточием рядом с ним, и появится меню выбора. В дополнение к этому визуальный редактор предлагает широкие возможности индивидуальной настройки других элементов, таких как изображения и таблицы. Возможно, вы заметили, что при создании проекта Quarto также создается файл _quarto.yml. Это документ спецификации всего проекта. Хотя все, что вы укажете в заголовке YAML своего документа, будет применено только к этой конкретной странице, все настройки, которые вы настроили в _quarto.
Краткий итог  129 yml, будут применены ко всем файлам. Вдобавок здесь можно указать такие параметры, как тип проекта, например книга/веб-сайт/статья. Возможно, вы также заметили, что в верхней части экрана есть кнопка publish. Кликните по ней, и узнаете, как публиковать свой документ Quarto в службе Quarto Pub, которая предоставляет простой и бесплатный способ делиться своей работой. Дополнительные сведения можно узнать на веб-сайте Quarto (https:// quarto.org/). 13.4. Краткий итог В этой главе были обследованы различные технологии редактирования текста, начав с удобных для пользователя редакторов в стиле WYSIWYG, таких как Google Документы и Microsoft Word, а затем перейдя к языкам разметки, таким как HTML, LaTeX и Markdown. Кроме того, в этой главе были представлены инструменты YAML и pandoc для конвертации форматов, а также система Quarto, которая интегрирует эти технологии, обеспечивая надежную платформу для создания разнообразных и профессиональных документов. В следующей главе будут рассмотрены возможности системы Quarto по макетированию подробнее.
Глава 14 Макетировние и ссылки на справочные материалы Теперь мы рассмотрим несколько базовых средств Quarto по макетированию, а также способы организации ссылок на научные публикации с помощью менеджера библиографических данных Zotero. 14.1. Пакет knitr Пакет knitr ликвидирует разрыв между исполнением исходного кода и генерацией документов PDF/HTML. Он исполняет исходный код и интегрирует его результат в файл Markdown, который затем конвертируется инструментом pandoc. С помощью пакета knitr можно настраивать параметры ячеек, чтобы управлять поведением блоков кода и их результатом. Указанные параметры размещаются в начале блока в комментариях. Например: ```{r} #| label: fig-plots #| fig-cap: Plots #| fig-subcap: #| – "Sunspot" #| – "US Population" #| layout-ncol: 2 # sunspot.year и uspop – это встроенные в R наборы данных plot(sunspot.year) plot(uspop) ``` В приведенном выше примере используется несколько опций пакета: label: fig-plots назначает метку фрагменту, fig-cap: Plots задает общий заго-
Блоки div  131 ловок, fig-subcap детализирует подзаголовки отдельных графиков («Sunspot» и «US Population»), а layout-ncol: 2 упорядочивает графики в две колонки. Другие часто используемые опции блоков кода таковы: Рис. 14.1  Графики Примечание 14.1. Опции пакета knitr можно использовать в заголовке YAML документа или проекта, чтобы применять их ко всем блокам кода в документе или ко всем блокам кода в проекте! Таблица 14.1. Шпаргалка по упрощенной разметке Markdown в R Опция eval echo Значение true true warning error message include tidy results true false true true false «разметка» cache false Описание Указывает, следует ли вычислять и включать код Определяет, следует ли выводить на экран код вместе с результатами Управляет выводом предупреждений на экран Управляет выводом ошибок на экран Управляет выводом сообщений на экран Предотвращает вывод любых данных (кода, результатов) Аккуратно форматирует код при выводе на экран Определяет формат вывода (разметка, как есть, удержание, скрытие) Кеширует результаты для последующей отрисовки 14.2. Блоки div Те, кто знаком с языком разметки HTML, будут знакомы с блоками <div>. Их можно создавать, заключая текст в три ::: или более двоеточий. Они широко применяются для размещения изображений в решетку, как показано ниже: ::: {layout-ncol="2"} ![Coit Tower](coit_tower.pdf) ![Sutro Tower](sutro_tower.pdf) :::
132  Макетировние и ссылки на справочные материалы Блоки <div> должны быть изолированы от соседних блоков пустыми строками. Они также могут быть вложены в другие блоки <div>. Короткий код pagebreak позволяет вставлять нативный разрыв страницы, совместимый с различными форматами: First Page {{< pagebreak >}} Second Page Разные языки, такие как R, YAML, HTML и LaTeX, имеют свой собственный синтаксис комментирования. Универсальным синтаксисом комментирования в Quarto является стиль HTML <!–здесь расположен комментарий --> 1. 14.3. Диаграммы Элегантные диаграммы UML создаются в Quarto с помощью таких инструментов, как Mermaid и Graphviz. Например, следующая ниже блок-схема была создана с помощью инструмента Mermaid: flowchart LR A[Тупой угол] --> B(Закругленный угол) B --> C{Решение} C --> D[Результат один] C --> E[Результат два] 1 Для того чтобы сделать строку текста комментарием, в среде RStudio используется сочетание клавиш Ctrl+Shift+C (или Command+Shift+C в macOS).
Цитирование  133 Результат один Тупой угол Закругленный угол Решение Результат два 14.4. Цитирование «Правильное цитирование повышает доверие к вашей работе и подтверждает значимость работы других людей». ChatGPT Цитирование источников в вашей работе оптимизируется интеграцией системы Quarto с менеджером библиографических данных Zotero. Quarto использует инструмент pandoc для генерирования ссылок на источники и биб­ лиографических списков в выбранном стиле. Для того чтобы организовать ссылки на источники цитат, надо вставить файл .bib или .bibtex, а при необходимости файл .csl с описанием стиля цитирования, в заголовок YAML: bibliography: references.bib При этом источники цитируются в документе, используя @yourcitation9999; при первом упоминании источника Quarto создаст для вас файл цитирования. В визуальном режиме предлагаются рекомендации, а при вводе идентификатора цифрового объекта (Digital Object Identifier, аббр. DOI) статья будет добавлена, даже если ее нет в вашей библиографии. Подробное описание методов цитирования можно найти в Quarto Citation и Pandoc Citations. Формат Markdown @abadie2017 says cluster your SE. Some thing smart [@abadie2017; @bai2009]. Abadie says cluster [-@abadie2017]. Результат (формат автор−дата) Abadie et al. [1] says cluster your SE. Some thing smart [1, 2]. Abadie says cluster 2017. Менеджер Zotero упрощает добавление цитирований в документ. При наборе текста он предлагает ссылки на источники для библиографического файла. Для документов, содержащих более 10 ссылок, следует использовать более удобный формат Bibtex; для этого достаточно только, чтобы Zotero был открыт. Для генерации цитат из документа (например, цитируемого в Obsidian) без ручного рецитирования следует использовать функцию bbt_update_bib() из пакета rbbt. Убедитесь, что менеджер Zotero активен и вы находитесь в документе Markdown, который хотите обновить. Функция bbt_update_bib() создаст библиографию. С помощью дополнительных аргументов можно ука-
134  Макетировние и ссылки на справочные материалы зать путь path_rmd в качестве пути к документу и путь path_bib в качестве пути к библиографическому файлу. 14.5. Краткий итог В этой главе был рассмотрен инструмент knitr, служащий для интеграции кода в документы, подчеркивая такие средства, как опции блоков кода и макеты блоков div. Также была затронута тема создания UML-диаграмм с помощью инструментов Mermaid и Graphviz и использование менеджера Zotero для цитирования в системе Quarto. В следующей главе вы узнаете о том, как эффективно сотрудничать с менее технически заинтересованными сторонами с помощью системы Google Документы, а также познакомитесь с различными вариантами обычного и шаблонного форматирования документов, доступными в системе Quarto.
Глава 15 Совместная работа и шаблонное форматирование документов 15.1. Оптимизация совместной работы с помощью инструмента trackdown В проектах, в которых участвуют сотрудники с разным уровнем технической подготовки, использование файлов Markdown может представлять проблему для некоторых заинтересованных сторон. Хотя в целях упрощения правки эти файлы можно было бы конвертировать в документ Microsoft Word, а затем перенести изменения обратно в Markdown, этот процесс может оказаться обременительным. Наша цель – оптимизировать рабочие процессы и эффективно повысить производительность. Инструмент trackdown предлагает отличное решение, позволяя редактировать текст совместно с помощью Google Документы. Для редактирования файлов .qmd необходимо иметь пакет trackdown версии 1.3 или выше, доступный для скачивания с GitHub командой: # install.packages("remotes") remotes::install_github("claudiozandonella/trackdown") library(trackdown) В настоящее время предоставляемые вместе с пакетом учетные данные Google API исчерпаны, и пользователям необходимо настраивать свои собственные учетные данные. Эта настройка упрощена благодаря руководству
136  Совместная работа и шаблонное форматирование документов от разработчиков, доступному по адресу: https://claudiozandonella.github.io/ trackdown/articles/oauth-app-configuration.html. Примечание 15.1. Если вы хотите использовать файлы из общей папки, владельцем которой вы не являетесь, то это не сработает. Необходимо быть владельцем папки либо использовать общий диск. После того как он будет сконфигурирован, скачать ваш файл .qmd в Google Документы будет очень просто с помощью команды upload_file("ваш_файл. qmd"). Что касается включения исходного кода, рисунков, таблиц или результатов анализа, то добавлять их непосредственно в Google Документы не получится. Вместо этого надо, чтобы документ был сперва скачан и все предложенные правки от сотрудников были просмотрены и приняты (либо отклонены) в Google Документы. Для оптимизации этого процесса можно воспользоваться опцией Tools (Инструменты) → Review suggested edits (Просмотреть предлагаемые правки) → Accept all (Принять все), перед тем как скачивать документ посредством команды download_file(file = "ваш_файл. qmd"). Реализуйте необходимые изменения локально и, при необходимости, используйте команду update_file("ваш_файл.qmd") для дальнейших обновлений на Google Диске. Примечание 15.2. Во избежание потери данных не забудьте сохранить свой файл перед его закачиванием на сервер или обновлением. В качестве полезного совета рекомендуется использовать команду render_ file("ваш_файл.qmd"), которая одновременно выполняет скачивание с сервера и отрисовку файла, что позволяет быстро просматривать отрисованный документ и эффективно управлять правками. Система Google Документы рекомендуется исключительно для описательного текста, а для управления исходным кодом следует использовать Git. Такой подход предотвратит ошибки, которые могут возникать при редактировании исходного кода в среде Google Документы. Любое программирование должно выполняться в интегрированной среде разработки (IDE), такой как RStudio. Следует учитывать, что примененное в Google Документы форматирование сохранено в trackdown не будет; вместо этого для форматирования надо использовать синтаксис упрощенной разметки Markdown. Этот рабочий поток поощряет итеративную совместную работу, чередуя редактирование описательного текста на Google Диске и локальное программирование с помощью Git. Важно отметить, что инструмент trackdown не поддерживает одновременное редактирование описательного текста и исходного кода; следовательно, для обеспечения эффективной совместной работы важно структурировать рабочий поток последовательно. В целях сведения к минимуму возможных конфликтов между исходным кодом и описательным текстом следует ограничивать использование исходного кода R в файле Quarto и подразделять исходный код на разные файлы. Такое подразделение создает две отдельные системы для текстового изложения и исходного кода, обеспечивая бесшовную интеграцию.
Шаблонное форматирование документов  137 Правка исходного кода Таблицы, графики trackdown Правка изложения Рис. 15.1  Рабочий поток совместной работы По завершении написания текста его необходимо правильно отформатировать; в следующем далее разделе будут кратко обследованы несколько вариантов. 15.2. Шаблонное форматирование документов Форматирование документа в соответствии с конкретными требованиями, например к журналам, диссертациям, отчетам или корпоративным стилям, бывает утомительно, но выполнение этой работы просто необходимо. Су­ щест­вует масса подходов к ее выполнению, и система для создания документов и отчетов Quarto предоставляет ряд предопределенных шаблонов, или заготовок, доступных для отрисовки документа Quarto. Эти шаблоны доступны для редактирования и расширения, хотя можно создать собственный шаблон, но это довольно непросто. Вместо того чтобы углубляться в индивидуальную настройку, рекомендуется обследовать шаблоны, созданные другими пользователями. Отличным местом для начала поиска конкретного журнального шаблона является секция расширений на веб-сайте Quarto. Если вы не уверены, какой шаблон использовать, подумайте о том, чтобы обследовать варианты, предлагаемые для крупнейшего научного издательства Elsevier1. Если у вас уже есть на примете площадка для публикации, то предварительное скачивание соответствующего шаблона поможет избавить вас от трудоемкого перехода позже. К большинству шаблонов прилагаются четкие инструкции по установке. Для тех, кто нуждается в дополнительной донастройке, в особенности для документов LaTeX, включение вашего Quarto’вского результата LaTeX в шаб­ лон Overleaf обеспечивает гораздо больший контроль над внешним видом документа, позволяя редактировать код LaTeX напрямую. Однако навигация по параметрам форматирования может оказаться сверхобременительной, поэтому по возможности рекомендуется упрощать работу и опираться на результаты работы других пользователей. Если в вашей организации требуется использование документов Microsoft Word и работа с ними может показаться обескураживающей, то существуют 1 См. https://github.com/quarto-journals/elsevier.
138  Совместная работа и шаблонное форматирование документов решения, облегчающие данный процесс. Справочный документ pandoc по Microsoft Word упрощает преобразование разметки Markdown в Microsoft Word, обеспечивая относительно простое оформление документа. В случае более сложных задач по стилизации существуют пакеты officedown и officer, которые предоставляют инструменты, точно соответствующие требованиям к стилю, позволяя сосредоточиваться на содержании, а не на форматиро­ вании. 15.3. Краткий итог Инструмент trackdown расширяет возможности совместной работы за счет интеграции Google Документы в части редактирования и упрощения рабочего потока, делая его доступным и эффективным для сотрудников с различными техническими навыками. Шаблоны Quarto и внешние ресурсы, такие как Elsevier1 для журналов, упрощают соблюдение конкретных требований к форматированию документов. Онлайновая платформа Overleaf предоставляет пользователям LaTeX расширенные возможности по индивидуальной настройке, тогда как такие инструменты, как pandoc и officedown, упрощают оформление документов Microsoft Word, позволяя авторам сосредоточиваться на содержании. Теперь давайте перейдем к части книги, посвященной сбору данных, начиная с главы, посвященной суммарной ошибке опроса. 1 См. https://www.elsevier.com/researcher/author/policies-and-guidelines.
ЧАСТЬ IV Сбор данных
Глава 16 Суммарная ошибка опроса Если вы читаете эту книгу, то, скорее всего, знакомы с основными статистическими показателями, в особенности со стандартной ошибкой. А если вы – экономист, то знаете, как сложно бывает справляться со систематическим смещением. Мы разведаем составляющие суммарной ошибки опроса (Total Survey Error, аббр. TSE) и методы их минимизации, повышающие качество и надежность результатов опроса. В дополнение к этому углубимся в вопросы разработки опроса, включая постановку целей, взятие выборки, составление вопросов и инструменты опроса. Давайте начнем с вопроса: что такое опрос? Ответ может показаться простым, но важно четко усвоить понятие. Формальное определение, данное Гроувсом и др. [14], выглядит следующим образом: Опрос – это систематический метод сбора информации у (выборки) сущностей с целью построения количественных описаний атрибутов более крупной популяции, членами которой являются сущности. Более понятное для человека определение, которое я предпочитаю, дано Кэролайн Джарретт [19]: Опрос – это процесс сбора ответов на вопросы у (выборки) людей с целью получения чисел, которые можно будет использовать для принятия решений. Обратите внимание, что опрос – это не просто серия вопросов, которые можно было бы назвать анкетой, или вопросником. Это целая операция, которая, помимо составления анкеты, предусматривает распространение во-
Краткий итог  141 просов, сбор информации у целевой популяции и обработку ответов с целью извлечения значимых сведений. Каждый из этих этапов представляет собой отдельную область знаний. Что делает опрос заслуживающим доверия? Ответ заключается в его точности, эффективной разработке и минимальной ошибке (погрешности). Суммарная ошибка опроса (TSE) [14] – это своего рода каркас, позволяющий исследователям выявлять и устранять различные ошибки, которые могут проявляться в опросах. Правильное понимание этих ошибок позволит вам принимать упреждающие меры с целью их минимизации. Суммарная ошибка опроса состоит из нескольких компонентов: Сторона измерения Ошибка в спецификации + Ошибка в измерении + Ошибка в обработке + Суммарная ошибка опроса = Ошибка в охвате + Ошибка выборки + Ошибка отсутствия ответов Сторона представления Первые три ошибки – ошибки в спецификации, измерении и обработке – представляют собой ошибки проведения измерений, которые включают в себя все ошибки, допущенные при создании, измерении и обработке анкет. Последние три ошибки – ошибки в охвате, выборке и отсутствия ответов – являются частью ошибок репрезентативности и связаны с тем, насколько точно респонденты соответствуют целевой популяции. Измерение 1. Ошибка в спецификации: ошибки в спецификации проявляются в ситуациях, когда нет четкой связи между теоретическими концепциями или построениями и переменными опроса. Важно обеспечивать, чтобы вопросы опроса точно отражали предписанные концепции. Недостаточно проницательные вопросы дают неинформативные результаты, поэтому очень важен тщательный обзор научных публикаций. Ошибка в спецификации может быть очень тонкой. Например, довольно сложно измерить доверие. Вопрос «Насколько вы доверяете по шкале от 1 до 10?» слишком неоднозначен. Вместо этого исследователи задают вопросы о различных аспектах доверия, таких как доверие к незнакомым людям, правительству и друзьям. У ответов на них есть базовая скрытая причина: «доверие», которое измеряется путем агрегации ответов в комплексный индекс доверия. 2. Ошибка в измерении: ошибки в измерении возникают из-за расхождений между расчетным значением и «истинным» значением, которые часто объясняются элементами разработки опроса. Такие ошибки могут быть связаны с неточностями в формулировке вопроса, вариантов ответа или толковании респондентом. Например, к ошибке измерения
142  Суммарная ошибка опроса могут приводить опросы о потреблении продуктов питания, основанные на памяти респондентов, ввиду неточного запоминания или понимания размеров порций. 3. Ошибка в обработке: эти ошибки связаны с проблемами, возникающими при сборе данных опроса и управлении ими. Они могут включать неточности при вводе данных, ошибки в программировании или другие нестыковки, которые могут возникать в процессе обработки данных. Такие ошибки особенно распространены при проведении физических обследований, в которых ручной ввод данных может приводить к ошибкам из-за соскальзывания пальца или неправильного толкования почерка. Дополнительные ошибки могут допускаться на этапах очистки и кодирования данных. Переход к электронным опросам помогает смягчать многие из этих распространенных проблем за счет снижения вероятности человеческой ошибки. Репрезентативность 1. Ошибка в охвате: ошибки в охвате возникают в ситуациях, когда отдельные лица из целевой популяции отсутствуют в выборочных рамках, использованных для взятия репрезентативной выборки. Такая ситуация может приводить к недопредставленности или перепредставленности определенных групп в рамках обследования. Например, исследование общего уровня физической подготовки, основанное на данных из фитнес-приложений, может значительно переоценивать средний уровень физической подготовки, поскольку оно в первую очередь охватывает группу любителей фитнеса. 2. Ошибка в выборке: ошибки в выборке возникают из-за того, что в ходе обследований данные обычно собираются из подмножества людей, а не из всей исследуемой популяции. Такие ошибки связаны с тем, что результаты выборки могут не всегда точно отражать истинные значения популяции. Например, опрос, в ходе которого случайным образом отбирается тысяча человек из города для оценки среднего дохода его жителей, может дать результаты, отличные от истинного среднего дохода всего населения города, исключительно из-за присущей выборке вариативности. 3. Ошибка отсутствия ответов: ошибки, связанные с отсутствием ответов, возникают в ситуациях, когда отобранные для опроса люди решают не участвовать в нем либо не дают исчерпывающих ответов. Такая ситуация может приводить к систематическому смещению, если респонденты, не ответившие на опрос, существенно отличаются от респондентов по ключевым аспектам. Это особенно часто встречается в онлайновых обзорах, где люди, у которых был хороший опыт работы с товаром, не оставляют отзывов, но те немногие покупатели, которым продукт не понравился, оставляют отрицательные отзывы. Далее будет рассмотрен каждый из этих этапов и сформировано представление о том, как избегать распространенных ошибок.
Репрезентативность – люди, которых вы спрашиваете  143 Давайте начнем с определения ошибок и постановки целей. Полезность опроса определяется тем, какую информацию он дает. Принцип здесь прост: «задавая глупые вопросы, получишь глупые ответы». Прежде чем разрабатывать свой опрос, задайте себе вот эти три вопроса: 1. Что вы хотите понять? 2. Зачем вам нужно это понимание? 3. Какие решения будут приниматься на основе полученных ответов? В контексте предприятия рассмотрите следующие ниже три вопроса, которые направлены на достижение практических деловых целей: 1. Какие решения будут приняты в ходе опроса? 2. Какая информация необходима для принятия этих решений? 3. Как опрос улучшит понимание? Если вы только начинаете и ищете хороший исследовательский вопрос, то начните с проведения исчерпывающего обзора научных публикаций. Выявите пробелы в обсуждении и определите важность устранения этих пробелов. Затем определите проблему, примените теорию, чтобы сформировать гипотезы, и определитесь с методами тестирования. Очень важно потратить значительное количество времени на чтение научных публикаций и формирование солидного понимания предметной области, методов и результатов исследований. Это ляжет в основу всего вашего проекта. Установив четкие цели своего проекта, вы не только сэкономите время, но и избежите ошибок в спецификации. 16.1. Репрезентативность – люди, которых вы спрашиваете Достижение репрезентативности в опросах имеет решающее значение для получения сбалансированного представления о популяции. Этим обеспечивается точное отражение отобранной выборкой характеристик, мнений или линий поведения более крупной популяции. Стремление к репрезентативности обеспечивает всестороннюю картину, которая точно отражает истинное разнообразие исследуемой популяции. Подумайте, насколько весомо выбранная группа птиц представляет более крупную стаю. Считаете ли вы, что случайная выборка на рис. 16.1 весомо представляет всю стаю на рис. 16.2? Определенно нет! Не хватает целого ряда птиц, при этом тут есть несколько других. Кажется, им нравится собираться в группы. Есть также нахальный попугай ара, который даже не входит в интересующую нас стаю.
144  Суммарная ошибка опроса Рис. 16.1  Случайная выборка птиц Рис. 16.2  Популяция птиц
Репрезентативность – люди, которых вы спрашиваете  145 16.1.1. Взятие выборок В ходе полевых исследований мы взаимодействуем с участниками и собираем их ответы. Однако крайне важно учитывать потенциальные проблемы, связанные с охватом желаемой целевой группы. Для того чтобы проиллюст­ рировать эти соображения, приведем пример проведения опроса с целью понять привычки употребления кофе студентами университетов в кампусе. 1. Целевая популяция: конкретная группа, которую мы стремимся понять или представить с помощью опроса. – Нас интересуют все студенты университетов, проживающие в кампусе, независимо от их специальности. 2. Рамки выборки: список или источник, из которого была взята выборка для опроса, обеспечивающие ее соответствие целевой популяции. – Для выявления потенциальных участников было решено использовать записи о зачислении в университет, тем самым обеспечивая, чтобы участники действительно являлись студентами. 3. Опрашиваемые люди: это лица, к которым мы обращаемся для участия в опросе, отобранные на основе рамок выборки и целевой популяции. – Основываясь на данных о зачислении, мы обращаемся к студентам в различных местах кампуса – библиотеках, кафетериях и учебных залах – с просьбой заполнить анкету. Мы должны учитывать, что те, кто не проводит время в этих местах, не попадают в выборку! 4. Отвечающие люди: участники, которые добровольно предоставляют свои ответы. – Из числа студентов, которых мы опросим, только те, кто решит пройти наш опрос, предоставят искомую информацию. У этой группы может быть более твердое мнение о кофе или больше свободного времени для участия в опросах, что важно учитывать при анализе данных. Надежность и достоверность результатов опроса повышается благодаря тщательному продумыванию целевой популяции, использованию надлежащих рамок выборки, эффективному привлечению участников и анализу характеристик респондентов. Для обеспечения успешности опроса необходимо очертить целевую популяцию и рамки выборки. Однако получить полный охват бывает непреодолимо сложно. Недостаточный охват возникает в ситуациях, когда в рамках выборки неадекватно представлены определенные лица или группы из целевой популяции. Это может приводить к систематически смещенным результатам. И наоборот, избыточный охват означает включение в рамки выборки лиц или групп, которые не являются частью целевой популяции, что потенциально может приводить к сбору посторонних данных и систематическим смещениям. Примечание 16.1. Лучше опрашивать нужных людей, чем опрашивать много людей.
146  Суммарная ошибка опроса Целевая популяция Рамки выборки Опрашиваемые люди Отвечающие люди Рис. 16.3  Ошибка в выборке Целевая популяция Рамки выборки (а) Недостаточный охват Целевая популяция Рамки выборки (b) Избыточный охват Рис. 16.4  Целевая популяция и охват в рамках выборки В целях обеспечения репрезентативности выборки крайне важно сводить к минимуму недостаточный и избыточный охваты. Этого можно достигать, методично формируя рамки выборки с учетом таких аспектов, как демография, местоположение, рекламная стратегия и временны́е ограничения. Ключом к решению любых проблем с охватом, которые только могут возникнуть, являются частое оценивание и корректировка рамок выборки. Если вы случайно не попали в целевую популяцию, то вам, возможно, придется отправиться по стопам мистера Уорлдуайда на Аляску. В инциденте 2012 года Питбуль участвовал в рекламном ролике. По условиям ролика покупатели Walmart могли проголосовать за магазин, в котором артист потом выступит. Все дело в том, что задавать вопрос в интернете – все равно что задавать его всем, и ситуация приняла неожиданный оборот. Голосование было сорвано, и Питбуля отправили на Аляску. Это просто напоминание о том, что при проведении опросов крайне важно обеспечивать охват нужных людей и избегать непредвиденных результатов. 16.1.2. От чего зависят ответы На ответы участников опроса влияет целый ряд факторов, но тем не менее выделяется несколько ключевых: усилия, вознаграждение и доверие.
Репрезентативность – люди, которых вы спрашиваете  147 Эффективно воздействуя на эти три фактора, можно не только уменьшать количество ошибок отсутствия ответов, но и устранять ошибку в измерении. 1. Усилия: количество усилий, требуемых от участников для прохождения опроса, может существенно влиять на их желание участвовать. Продолжительные, сложные или отнимающие много времени опросы могут препятствовать участию, что приводит к снижению количества ответов. 2. Вознаграждение: участники нередко ищут какую-либо форму поощрения или выгоды за участие в опросе. Сюда могут входить материальные вознаграждения, такие как денежная компенсация или подарочные карты, или нематериальные вознаграждения, такие как удовлетворенность от участия в исследовании или личный интерес к теме опроса. Предложение соответствующих вознаграждений может побуждать участников давать точные и продуманные ответы. 3. Доверие: важную роль для поощрения открытых и честных ответов играет установление доверительных отношений с участниками опроса. Участники должны быть уверены в том, что их конфиденциальность будет соблюдена, их данные будут надежно обработаны, а опрос будет проведен авторитетной организацией. Четкое информирование о мерах защиты данных и этических соображениях помогает устанавливать доверие и повышает вероятность получения надежных ответов. Принимая во внимание требуемые усилия, предоставляя соответствующие вознаграждения и укрепляя доверие к процессу опроса, можно создавать атмосферу, способствующую получению от участников высококачественных ответов. В интересном исследовании, проведенном Джоном и соавт. [20], были осуществлены эксперименты с целью понять факторы, влияющие на готовность людей раскрывать личную информацию. Один из примечательных экспериментов включал изменение дизайна страницы опроса и наблюдение за его влиянием на уровень раскрытия. Для участия в исследовании были привлечены студенты Университета Карнеги-Меллон, и в название опроса и его интерфейс были внесены изменения. Опрос, оформленный в легкомысленном стиле, носил юмористическое название «Насколько вы плохи?» и содержал ярко-желтый фон, красный текст и мультяшную иконку дьявола, напоминая беззаботную онлайновую викторину, призванную преуменьшить вопросы конфиденциальности. И наоборот, в базовой формулировке опрос был представлен в профессиональном контексте: «Исследование этических стандартов Университетом Карнеги–Меллона». Интересно, что участники, участвовавшие в фривольной формулировке, в среднем в 1,7 раза чаще признавались в деликатном поведении по сравнению с теми, кто участвовал в базовой формулировке. Например, люди в фривольной формулировке более чем в два раза чаще признавались в том, что фотографировали себя или партнера обнаженными: в фривольной формулировке признались 31,8 % по сравнению с 15,7 % в базовой формулировке.
148  Суммарная ошибка опроса Эти результаты свидетельствуют о том, что люди могут чувствовать себя более непринужденно, делясь личной информацией на платформах, которые не выглядят строго профессиональными, даже если эти платформы могут представлять более высокий риск неправомерного использования данных. Результаты подчеркивают сложную взаимосвязь между контекстом, доверием и раскрытием применительно к личной информации. 16.2. Разработка вопросов Теперь давайте сосредоточимся на сути любого опроса – самих вопросах. Мы рассмотрим общие трудности, такие как качество вопросов, критически важная роль порядка их следования, последствия включения ответов «затрудняюсь ответить» («ни один из вышеперечисленных») и влияние продолжительности опроса. 16.2.1. Ответы на вопросы Согласно Туранжо и соавт. [29], ответ на вопрос опроса предусматривает четыре ключевых шага. Эти шаги дают ценную информацию о мыслительном процессе респондентов. 1. П  онять вопрос: первым шагом при ответе на вопрос опроса является понимание. Респондентам необходимо точно понять вопрос, чтобы дать осмысленный ответ. Поэтому первостепенное значение имеют ясность и удобочитаемость вопроса. Например, попытайтесь понять следующий ниже вопрос: Какой процент времени за последние пять рабочих дней вы использовали корпоративную коммуникационную программу? 2. Найти ответ: после того как вопрос будет понят, респондент должен порыться в своей памяти или базе знаний, чтобы найти подходящий ответ. Этот ответ должен основываться на имеющейся у него информации. Например: Вспомнить: 1. Какого цвета рубашка была на вас два вторника назад? 2. Какого цвета рубашку вы надели в канун Нового года? 3. Как вы отпраздновали свое 18-летие? 4. Что вы ели вчера на завтрак? 5. Когда началась гражданская война в Америке? 3. Вынести суждение об ответе: после определения потенциального ответа респонденты оценивают, удобно ли им будет поделиться своим мнением. В процессе принятия решения важную роль играют такие факторы, как конфиденциальность, социальная привлекательность и чувствительность информации. Например:
Разработка вопросов  149 Согласны или не согласны ли вы со следующим утверждением: «Я одобряю действия нынешнего руководства». 1. Полностью согласен 2. Согласен 3. Ни то, ни другое 4. Не согласен 5. Категорически не согласен Хотя вопрос кажется простым, выражение несогласия с действиями нынешнего руководства может иметь потенциальные последствия, такие как риск увольнения, если руководству станет известно об отсутствии у респондента поддержки. 4. Указать ответ: наконец, респондентам необходимо соответствующим образом соотнести свой ответ с предложенными вариантами ответов. Это может быть выбор конкретной категории, оценка по шкале или предоставление письменного ответа. Например: Какая у вас базовая специальность? Чем вы занимаетесь в своей карьере? Какая у вас базовая специальность? ________ Чем вы занимаетесь в своей карьере? ________ Уточнение вопросов опроса может значительно повышать качество получаемых ответов. Давайте попрактикуемся в использовании вопроса из первого пункта списка. Обратите внимание на свой мыслительный процесс во время ответа на вопрос и подумайте, как вы могли бы его улучшить: Какой процент времени за последние пять рабочих дней вы использовали корпоративную коммуникационную программу? С приведенным выше вопросом связано несколько трудностей. Во-первых, что такое «корпоративная коммуникационная программа»? Во-вторых, довольно сложно подсчитать процентное соотношение времени за последние пять рабочих дней, так как это относительно продолжительный период и ежедневные действия зачастую не совпадают. Следовательно, данный вопрос можно разбить на несколько более конкретных вопросов, которые будут устранять эти трудности: Какой процент времени в течение вашего последнего рабочего дня вы использовали программы для обмена сообщениями, помимо электронной почты (например, Slack, Discord, WhatsApp, Telegram)? Что вы используете для общения на работе? (Выберите все, что применимо)      Электронную почту Slack Discord WhatsApp Другое Ценные знания, полученные на основе психологии ответов при проведении опросов, помогают исследователям в разработке высококачественных
150  Суммарная ошибка опроса анкет, которые минимизируют нагрузку на респондентов, повышают качест­ во данных и улучшают общее восприятие результатов опроса. 16.2.2. Рекомендации по эффективной разработке вопросов Разработка вопросов – это, по сути, деятельность, ориентированная на человека. Она предусматривает разработку легко понимаемых вопросов, что позволяет респондентам без особых усилий вникать, оценивать и формулировать свои ответы. Хотя многие советы могут казаться общими и довольно очевидными, важно помнить об этих простых моментах. Я часто обращаюсь к рекомендациям Кросника по составлению анкет [22]. Ради упрощения ниже приведен список ключевых пунктов. 1. Использовать простые и знакомые слова для обеспечения ясности и понимания. Избегать технических терминов, жаргонизмов и сленга. 2. Избегать слов с неоднозначным значением с целью обеспечения одинакового толкования вопросов респондентами. 3. Задействовать простые структуры предложений и синтаксис с целью облегчения понимания. 4. Делать вопросы детальными и конкретными, а не обобщенными и абстрактными, с целью получения связных и надежных ответов. 5. Избегать наводящих вопросов или вопросов с заранее известным ответом, которые склоняют респондентов к определенному ответу. 6. Задавать по одному вопросу за раз во избежание путаницы и с целью получения точных ответов. Избегать двояких вопросов, в которых объединяется несколько тем. 7. Избегать вопросов с одинарным или двойным отрицанием, так как они могут сбивать с толку и приводить к неправильному толкованию, даже если некоторые дисциплины требуют, чтобы часть вопросов содержала отрицание. 8. Предоставлять исчерпывающие (охватывающие все возможные варианты) и взаимоисключающие (не пересекающиеся между собой) варианты ответов. Есть еще много чего, что нужно учитывать, но это должно устремить ваши мысли в правильном направлении. Настоятельно рекомендуется ознакомиться с другими работами Кросника, включая его статьи, книги и семинары. 16.2.3. Влияние порядка следования вопросов Порядок, в котором представлены вопросы в опросе, может существенно влиять на качество ответов и уровень вовлеченности респондентов. Эффективная очередность вопросов имеет решающее значение для сбора достоверных данных. Вот несколько соображений, которые следует иметь в виду:
Разработка вопросов  151 1. Начинать с простых и приятных вопросов, чтобы установить взаимопонимание и повысить доверие респондентов. 2. Начинать с вопросов, непосредственно касающихся главной темы, как это было описано респонденту перед опросом. 3. Группировать соотносящиеся вопросы вместе, чтобы сохранять последовательность и связность. 4. Выстраивать очередность вопросов по определенной теме, от общего к частному, постепенно сужая тематику. 5. Размещать деликатные вопросы, которые могут вызывать у респондентов дискомфорт, ближе к концу анкеты, чтобы участники могли подготовиться к обсуждению личных или деликатных тем. 6. Включать вопросы-фильтры во избежание запросов сведений, не относящихся к делу. Этим обеспечивается, что участники будут отвечать только на те вопросы, которые относятся к ним лично. Если вы ищете проверенные анкеты, то настоятельно рекомендуется воспользоваться репозиторием, созданным Габриэлем Гилмором (Gabriel Gilmore) и Сарой Финни (Sara Finney)1, в котором представлена обширная коллекция проверенных анкет. В дополнение к этому отличным источником вопросов является серия «Справочник по маркетинговым шкалам» [8], являющаяся самой продолжительной серией книг, содержащих обзоры разнородных показателей, используемых в научных исследованиях поведения потребителей. 16.2.4. В опросе говорится: «Бекон»! Давайте рассмотрим пример того, как намеренно ущербная постановка вопросов опроса и толкование их результатов могут приводить к вводящим в заблуждение выводам. Компания-производитель бекона обратилась к известному специалисту по связям с общественностью Эдварду Бернейсу (Edward Bernays) с просьбой увеличить продажи. В начале Бернейс провел исследование и обнаружил, что плотный завтрак, вероятно, полезен для здоровья. Вооружившись этой информацией, он обратился к врачу из своей команды и попросил его поддержать, что привело к опросу, который был разослан 5000 коллегам, и все они согласились с пользой плотного завтрака для здоровья. Результаты были разосланы в средства массовой информации, а их кульминацией стали заголовки, гласящие: «4500 врачей призывают американцев плотно завтракать, чтобы улучшать свое здоровье». Это одобрение, наряду с предложением включать в меню завтрака яичницу с беконом, оказало значительное влияние на общественное мнение, навсегда изменив привычки американцев завтракать. 1 См. https://www.jmu.edu/assessment/sass/_files/database_of_existing_measures_3.8.21. pdf.
152  Суммарная ошибка опроса Стоит отметить, что речь шла не о конкретном продукте питания – беконе – как таковом. Просто Бернейс воспользовался возможностью привести продукт в соответствие с более широким представлением о здоровье, успешно увеличив продажи бекона и сформировав культуру американских завтраков. Что не так с вопросом, который они задали, и их выводами? Что полезнее для здоровья – легкий завтрак или существенный завтрак? 1. 2. Легкий Существенный «4500 врачей призывают американцев есть плотные завтраки, чтобы укрепить свое здоровье»: ешьте больше яиц и бекона на завтрак! Этот вопрос содержит ошибку в спецификации, так как в нем не говорится непосредственно о последствиях употребления яиц и бекона для здоровья, а содержится общий запрос о количестве завтрака. Вдобавок термин «су­ щественный» несколько абстрактный и двусмысленный, поскольку он является синонимом «достаточный», что может приводить к неправильному истолкованию, когда респонденты будут думать, что «существенный» означает просто «адекватный», а не «большой» или «сытный». Более того, вызывает сомнения выбор целевой популяции. Врачи, несмот­ ря на свои медицинские знания, могут не обладать специализированными знаниями в области питания, которыми обладают диетологи. Рамки выборки для опроса были ограничены составленным практикующим врачом списком рассылки, который может неточно отражать взгляды более широкого медицинского сообщества на диетологию. Сделанный по результатам опроса вывод затем ошибочно экстраполируется с «существенного» завтрака на «плотный» завтрак и впоследствии привязывается непосредственно к потреблению яиц и бекона без достаточных данных, подтверждающих такую конкретную диетическую рекомендацию. Указанный логический скачок чрезмерно упрощает и искажает первоначальные результаты опроса, потенциально нанося вред разнообразному населению с различными потребностями в области здравоохранения и диетическими ограничениями. 16.2.5. Типы вопросов Различные типы/форматы вопросов в анкете позволяют выявлять различные типы данных. Ниже приведены три наиболее часто используемых формата вопросов: 1. Вопрос с выбором из одного варианта ответа: идеально подходит для вопросов, в которых респондентам предлагается выбрать только один вариант ответа из списка возможных. В онлайновых опросах респондент выбирает один вариант, нажав на соответствующую радиокнопку. 2. Вопрос с выбором из нескольких вариантов ответа: подходит для вопросов, которые позволяют респондентам выбирать несколько вари-
Разработка вопросов  153 антов ответа из списка. Распространенная форма заключается в установке нескольких флажков, чтобы респонденты могли их отмечать и указывать свой выбор. 3. Вопрос открытого типа: используется в ситуациях, когда респондентам необходимо предоставить письменный ответ или ввести данные, не предусмотренные заранее заданными параметрами. Обычно вопросы открытого типа представлены текстовыми полями, позволяющими пользователям свободно вводить свои ответы. Правильное использование этих форматов вопросов гарантирует, что анкета будет содержать необходимую информацию и предоставит четкие варианты ответов. Вместе с тем важно предоставлять четкие инструкции о том, как участники должны вводить свои ответы; в противном случае данные могут быть неточно истолкованы. Показанный на рис. 16.5 формат не дает участникам указаний о том, как давать свои ответы, в результате чего способ указания ответа – как правило, посредством галочки – у разных респондентов сильно различается: некоторые ставят галочку посередине, некоторые сверху, а некоторые снизу, что чрезвычайно затрудняет истолкование выбранного ответа. Кроме того, почерк может создавать двусмысленность, например цифры 1 и 7 часто кажутся очень похожими. Более эффективный подход состоял бы в том, чтобы попросить участников обвести число кружком, поставить флажок рядом с каждым ответом или предложить варианты ответов, чтобы не требовать от респондентов записывать свои ответы. Выбор формата вопроса должен соответствовать характеру вопроса и типу искомого ответа. Продуманный подход уменьшит количество ошибок в обработке и упростит ввод данных. (а) Это двойка (b) Единица или семерка? Рис. 16.5  Ответы без инструкций 16.2.6. Шкалы Лайкерта Шкалы Лайкерта обычно используются в опросах для измерения установок, мнений и восприятий. Вы, вероятно, с ними сталкивались, отвечая на вопросы, в которых используется диапазон «согласен − не согласен». Вот несколько общих соображений при выборе количества баллов в шкале.
154  Суммарная ошибка опроса 1. 5 или 7 баллов: широкое применение находят как 5-, так и 7-балльные шкалы. Они предлагают достаточно вариантов ответов, чтобы отражать различные мнения. Как правило, между этими двумя вариантами ответов нет существенной разницы. 2. Учет удобства для респондентов: использование меньшего коли­ чества баллов в шкале, например 5, облегчает респондентам быстрый выбор ответа. Это приводит к более высокому количеству ответов и снижению утомляемости респондентов. 3. Более высокие баллы за особые потребности: в некоторых случаях может потребоваться большее количество баллов в шкале, чтобы учесть нюансы ответов или когда требуется более высокая точность. Это может быть актуально в специализированных исследованиях или при изучении специфических установок либо линий поведения. 4. Следование установленным протоколам: если опрос является частью­более масштабной учебной работы или научного исследования, то рекомендуется использовать шкалу баллов, обычно применяемую в заданном контексте. За счет этого обеспечивается состыкуемость и сопоставимость с существующими исследованиями. Примечание 16.2. В конце концов, кто устанавливает шкалу, тот и платит. В конечном счете решение о количестве баллов в шкале остается за разработчиком опроса, который должен учитывать конкретные цели исследования, целевую аудиторию и практические соображения. Руководство по конструированию вопросов с использованием шкал Лайкерта можно найти в документе «Варианты ответов по шкале Лайкерта»1, основанном на работе Вейджеса [32]. 16.2.7. Варианты «не знаю» и «затрудняюсь ответить» Включение в опросы вариантов ответа «не знаю» и «затрудняюсь ответить» может влиять на качество данных. Кросник и соавт. [23] провели обследование влияния вариантов ответа «нет мнения» и их влияние на качество данных, выделив потенциальные издержки, связанные с их включением. Вот несколько соображений, которые следует учитывать. 1. Потенциальное влияние на качество данных: включение ответов «не знаю» и «затрудняюсь ответить» необязательно может улучшать качество данных. Иногда их включение может ограничивать измерение осмысленных мнений, предоставляя «легкий выход» респондентам, которые в противном случае могли бы дать вдумчивый ответ. 1 См. https://mwcc.edu/wp-content/uploads/2020/09/Likert-Scale-Response-Options_ MWCC.pdf.
Разработка вопросов  155 2. Влияние умственной усталости: респонденты, испытывающие усталость или неуверенность в своем мнении, могут выбирать нейтральные варианты, например «не знаю», что приводит к увеличению доли нейтральных ответов и потенциальной маскировке подлинных установок. 3. Опциональные вопросы: все вопросы в опросе являются опциональными. Респонденты могут пропускать вопросы, на которые они не хотят отвечать или которые к ним не относятся. За счет опциональности вопросов анкеты респонденты получают возможность отвечать только на те вопросы, на которые им комфортно отвечать или на которые они знают ответы. Эти факторы крайне важно учитывать при разработке опросов и принятии решения о том, включать в них варианты ответов «не знаю» и «затрудняюсь ответить» или нет. 16.2.8. Продолжительность опроса Продолжительность опроса может существенно влиять на вовлеченность участников и качество данных. Ниже приведено несколько ключевых моментов, которые следует иметь в виду. 1. Процент отсева: в университетских учебных работах, проводимых через интернет [17], как правило, мгновенный процент отсева составляет около 10 %, с дополнительным снижением на 2 % в расчете на каждые 100 пунктов опроса. Следовательно, более продолжительные опросы могут приводить к более высокому уровню отсева, поскольку участники могут уставать или терять интерес. 2. Удовлетворенность и качество ответов: продолжительные опросы, в особенности в лабораторных исследованиях, могут приводить к удовлетворительному поведению [33] в ситуациях, когда участники дают «в меру сносные» ответы, вместо того чтобы давать продуманные и точные ответы. Это может негативно сказываться на качестве данных. Однако такие побочные эффекты могут влиять на совокупные результаты лишь незначительно [4]. 3. Анкеты для онлайнового маркетинга: при проведении онлайновых маркетинговых опросов рекомендуется сокращать продолжительность опроса [37]. Опросы, состоящие более чем из нескольких вопросов, могут приводить к значительному отсеву участников. Опросы продолжительностью более десяти минут настоятельно не рекомендуются из-за невозможности поддерживать вовлеченность участников. Разработчикам опросов следует стремиться балансировать получение необходимой информации со способностью респондентов справляться с опросом, чтобы обеспечивать оптимальную вовлеченность участников и качество ответов. Лично я предпочитаю не включать вариант «затрудняюсь ответить», если только есть вероятность того, что что-то не относится к конкретному че-
156  Суммарная ошибка опроса ловеку. По моему опыту, если делать вопросы опциональными (не заставляя людей отвечать) и исключать вариант «затрудняюсь ответить», то количество ответов на вопросы увеличивается. Вдобавок на ранних этапах, когда вы, возможно, мало что знаете о популяции, чрезвычайно полезно оставлять возможность для текста открытого типа, в котором участники смогут написать свой собственный ответ. Это позволяет людям сигнализировать о том, что вы могли пропустить какой-либо распространенный вариант ответа. Однако позже это может иметь неприятные последствия в более широком масштабе, поскольку некоторые могут отказаться от классификации своих ответов по заранее заданным категориям и просто помещать их в открытый текст, что потребует последующей ручной переклассификации. 16.2.9. Приглашение к опросу Приглашая людей к участию в опросе, очень важно устанавливать доверительные отношения и предоставлять необходимую информацию о поощрении участия. Ниже приводится краткое описание лучших образцов практики. 1. Знакомство: четкая идентификация себя и объяснение причины, по которой вы обратились к конкретному человеку, будут способствовать укреплению доверия и убедительности. 2. Цель и преимущества: изложение цели опроса и преимуществ учас­ тия в нем будет мотивировать респондентов. Объясните, как их ответы будут способствовать проведению исследования или процессу принятия решений. 3. Стимулы: если предусмотрены стимулы или вознаграждения, предлагаемые за участие в опросе, то любое их упоминание поможет мотивировать людей к заполнению анкеты. 4. Обзор опроса: предоставление обзора тем или вопросов, затронутых в опросе, способствует управлению ожиданиями и помогает участникам распорядиться своим временем. 5. Время завершения: указание крайнего срока или времени завершения опроса создает ощущение срочности и обеспечивает своевременность ответов. В дополнение к этому рассмотрите возможность добавления страницы с благодарностями после завершения опроса участниками. Она будет свидетельствовать о высокой признательности за потраченное ими время и учас­ тие. Четкое и лаконичное заявление о приватности, касающееся вопросов конфиденциальности, будет заверять участников в том, что их ответы останутся конфиденциальными и будут использованы исключительно в исследовательских целях. Наконец, изложение плана дальнейших действий даст участникам возможность узнать, будете ли вы делиться результатами опроса, и если да, то каким образом, или какие действия будут предприняты на основе полученных результатов. Включение этих элементов в приглашение к опросу повысит вовлеченность участников и улучшит общее впечатление от опроса.
Инструменты проведения опросов  157 16.2.10. Итеративное составление вопросов Итеративный подход предусматривает повторяющиеся циклы изучения, уточнения и масштабирования, направленные на повышение эффективности опросов. На первом шаге создается черновой вариант опроса, а затем проводится собеседование с кем-либо из целевой аудитории, чтобы определить, понятны ли ему/ей вопросы и имеют ли они отношение к делу. Следует обязательно уделять пристальное внимание всем аспектам опроса, таким как вопросы, инструкции, состав и распространение. На основе отзывов опрос будет отредактирован и уточнен в ходе обсуждений с более широкой группой людей (вполне достаточно десяти человек). Важно избегать первоначального распространения опроса среди всего целевого пула. Если после первоначального распространения будут необходимы изменения, то может не хватить участников для пересмотренного опроса, не говоря уже о потенциальной потере ресурсов. Такой итеративный подход позволяет исследователям извлекать ценные сведения из каждого взаимодействия, постоянно совершенствовать состав опроса и в конечном итоге охватывать более широкую аудиторию для проведения всестороннего анализа. Рассмотрев создание анкеты, теперь давайте рассмотрим вопрос о том, как распространять опрос среди участников. 16.3. Инструменты проведения опросов Исследователи имеют возможность выбирать из широкого спектра инструментов проведения опросов, каждый из которых обладает уникальными функциональными опциями и преимуществами. Понимание этих опций играет полезную роль для сбора данных. Теперь давайте рассмотрим разные способы проведения физических и цифровых опросов, а также платформы для рекрутирования участников. 16.3.1. Методы проведения физических опросов Традиционные методы проведения физических опросов предоставляют самые разные способы сбора данных, что особенно полезно в ситуациях, когда цифровой доступ ограничен. 1. Бумажные опросы: они универсальны, могут проводиться в различных условиях и, кроме того, не требуют использования ноутбуков или телефонов. 2. Личные интервью: этот метод позволяет напрямую взаимодействовать с участниками, разъяснять сложные вопросы и собирать подробные ответы.
158  Суммарная ошибка опроса 3. Телефонные опросы: эти опросы эффективны для сбора данных из географически распределенных выборок, но следует учитывать возможные отклонения, такие как исключение лиц, не имеющих телефонов. 4. Опросы по почте: этот подход охватывает широкий круг людей, в особенности тех, у кого нет доступа к интернету. Количество ответов и сроки выполнения могут варьироваться. 5. Опросы на перехвате: эти опросы предусматривают обращение к отдельным лицам в общественных местах по поводу участия, что позволяет немедленно собирать данные, однако могут возникать потенциальные проблемы с репрезентативностью и конфиденциальностью. При использовании всех физических методов необходимо соблюдать этические принципы сбора данных и обеспечивать конфиденциальность участников. Кроме того, необходимо обучение и надзор за ассистентами, которые проводят физические опросы. Также возможны гибридные подходы, когда участники заполняют анкету на ноутбуке или планшете или научный сотрудник заполняет ее в процессе собеседования. Несмотря на сложность с оперативной точки зрения, физические опросы нередко являются единственным способом сбора ответов из сельских районов. 16.3.2. Платформы для проведения цифровых опросов Различные платформы для проведения цифровых опросов удовлетворяют разным исследовательским потребностям, предоставляя целый ряд функ­ циональных средств, уровней удобства использования и затрат. 1. Google Формы1: предлагает удобные и бесплатные сервисы, подходящие для простых опросов или проектов с ограниченным бюджетом. 2. Typeform2: предоставляет интерактивный интерфейс для проведения опросов, повышая удобство работы с пользователями и количество ответов. Данная платформа на сегодняшний день позволяет создавать самые привлекательные опросы. 3. Qualtrics 3: всесторонняя платформа, поддерживающая комплексную разработку опросов с расширенными функциональными средствами, такими как условная логика, встроенные возможности распространения, возможности совместной работы и обширная индивидуальная настройка. Многие университеты имеют институциональную подписку на Qualtrics, поэтому обязательно проверьте, есть ли у вас доступ! 1 2 3 См. https://workspace.google.com/products/forms/. См. https://www.typeform.com/. См. https://www.qualtrics.com/.
Инструменты проведения опросов  159 4. SMARTRIQS1: инструмент с открытым исходным кодом, который ин­ тег­рируется с платформой Qualtrics в части проведения интерактивных пошаговых онлайновых экспериментов. 5. LimeSurvey2: индивидуально настраиваемый инструмент проведения опросов с открытым исходным кодом, идеально подходящий для проведения сложных опросов, в особенности в ситуациях, когда платформа Qualtrics недоступна. 6. O-tree3: данная платформа разработана специально для экономических экспериментов и социологических исследований с такими функциональными средствами, как игры для принятия решений, сбор данных в реальном времени и обработка платежей. 7. Z-Tree (Цюрихский инструментарий для готовых экономических экспериментов)4: программное обеспечение для разработки и проведения экономических экспериментов. Он предоставляет простой в освоении и использовании язык управления, позволяющий пользователям быстро проводить сложные эксперименты. 8. ChoiceFlow5: платформа для разработки и проведения сложных поведенческих экспериментов в режиме онлайн. Она поддерживает широкий спектр постановок экспериментов и бесшовно интегрируется с главнейшими онлайновыми рынками труда, позволяя исследователям эффективно рекрутировать и оплачивать участников. 16.3.3. Платформы для рекрутирования участников Такие платформы, как Amazon Mechanical Turk (MTurk), Prolific и Respondent, предлагают дополнительные возможности для проведения опросов, служа площадками для привлечения участников и выплаты им вознаграждения. 1. Amazon Mechanical Turk (MTurk)6: краудсорсинговая платформа, предоставляющая широкий спектр участников по относительно низкой цене, но с учетом справедливого вознаграждения и качества данных. 2. Prolific7: похожа на платформу MTurk, но специально разработана для академических исследований с предварительно отобранными участниками и акцентом на этические стандарты. 3. Respondent8: данная платформа специализируется на поиске профессионалов для проведения высококачественных исследований, что 1 2 3 4 5 6 7 8 См. https://www.smartriqs.com/. См. https://www.limesurvey.org/. См. https://www.otree.org/. См. https://www.ztree.uzh.ch/en.html. См. https://deckspire.com/products/choiceflow/. См. https://www.mturk.com/. См. https://www.prolific.com/. См. https://www.respondent.io/.
160  Суммарная ошибка опроса особенно полезно для исследований рынка B2B или исследований, требующих профессиональных знаний. 16.4. Краткий итог В этой главе была рассмотрена концепция суммарной ошибки опроса (TSE) и ее важнейшие компоненты: ошибки в измерении и в репрезентативности. Понимание этих ошибок и реализация стратегий по их минимизации необходимы для разработки надежных и эффективных опросов. Кроме того, была затронута тема важности четкой постановки целей, достижения репрезентативности и разработки хорошо продуманных вопросов для обеспечения точного сбора данных. Применяя передовые методы разработки опросов и используя инструменты как физического, так и цифрового опроса, исследователи могут повышать качество и достоверность результатов своих опросов. В следующей главе будет подчеркнута важность всесторонней исследовательской документации, уделяя особое внимание отслеживаемости, доступности и безопасности, а также даны практические советы по поддержанию высококачественных и воспроизводимых данных.
Глава 17 Документирование Всесторонняя документация имеет решающее значение для успеха любого исследовательского проекта, обеспечивая сбор взаимоувязанных данных и соблюдение установленных процедур сотрудниками на местах. В этой главе описывается важность документирования каждого процесса, связанного со взятием выборки, администрированием, сбором и обработкой данных. Примечание 17.1. Несмотря на всеобщую неприязнь к бюрократии, она, несомненно, необходима! 17.1. Принципы документирования Надежная система документирования основывается на нескольких основополагающих принципах. Составление и форматирование документов 1. Физическая и цифровая доступность: обеспечивает легкий доступ ко всей документации как в физическом, так и в цифровом формате. Организовывает физические документы для удобства поиска и обес­ печивает хранение цифровых документов таким образом, чтобы поддерживать быстрый и эффективный доступ. 2. Конвертируемость: позволяет легко конвертировать физические документы, такие как опросы и формы, в электронный формат. Способствует эффективному хранению, быстрому поиску и более легкому обмену информацией. 3. Единообразное форматирование: поддерживает связный внешний вид и структуру всех документов. Использует стандартные шаблоны и единообразную типографику с целью улучшения удобочитаемости и обеспечения легкого понимания пользователями документации и возможности ориентироваться в ней.
162  Документирование 4. Процесс обновления и проверки: устанавливает четкую процедуру регулярного обновления и пересмотра документов. Обеспечивает, чтобы информация оставалась адекватной, точной и актуальной. Регулярные ревизии помогают выявлять и исправлять ошибки или устаревший контент. Система документов 1. Централизация: объединяет всю документацию в единую систему. Минимизирует неоднозначность и обеспечивает, чтобы каждый пользователь имел доступ к самой актуальной и точной информации. 2. Иерархическая структура: в документации применяется четкая иерар­хическая структура, отражающая разные уровни, такие как уровни площадки, сеанса и испытуемых. Помогает пользователям легко перемещаться по документам и понимать взаимоотношения между разными разделами и темами. 3. Избыточность: обеспечивает стратегическую избыточность, дублируя ключевую информацию в нескольких форматах или местоположениях. Снижает риск потери данных и обеспечивает постоянный доступ к важной информации, даже если один из источников становится недоступным. 4. Устойчивость: документация разрабатывается таким образом, чтобы она могла противостоять хаотичным ситуациям. Включает в себя создание резервных копий, использование форматов, которые менее подвержены повреждению или потере, и обеспечение легкой реорганизации документов, если они окажутся неупорядоченными. 5. Защищенность и конфиденциальность: уделяет особое внимание защите конфиденциальной информации в документации. Предусмат­ ривает соблюдение законов о защите данных, внедрение надежных методов шифрования и обеспечение доступа к конфиденциальным данным только уполномоченным на то персоналом. Совместная работа с коллегами 1. Протоколы совместной работы и коллективного использования: определяют четкие протоколы совместного создания документов и обмена ими. Обеспечивают согласованность, предотвращают конфликты и снижают риск потери данных. Эффективные протоколы совместной работы помогают поддерживать целостность и взаимоувязанность документации. 2. Обучение и поддержка пользователей: обеспечивает всестороннее обучение и поддержку всех заинтересованных сторон, вовлеченных в процесс документирования. Гарантирует, что каждый сможет эффективно использовать систему документирования и вносить свой вклад в ее работу, что приводит к повышению качества и надежности документов.
Принципы документирования  163 17.1.1. Иерархическая структура документации Иерархическая структура проектной документации является важнейшим элементом, обеспечивающим эффективное управление и поиск данных в ходе исследования. Указанная структура обычно делится на три первичных уровня: площадку, сеанс и испытуемых, каждый из которых помечен уникальными идентификаторами и переменными для поддержания порядка и ясности. 001 Площадка Сеанс 021 Испытуемые 005 Рис. 17.1  Иерархия документации В самом широком смысле проект охватывает все аспекты исследования, включая анализ, цели, методологии, обязанности и документацию. В нем представлен всесторонний обзор всей исследовательской инициативы с указанием ее масштабов и целей. Уровень площадки, идя следующим за уровнем проекта, представляет собой наиболее широкую классификацию в рамках проекта. Обычно он относится к физическому или концептуальному местоположению исследования, например к площадке проведения эксперимента. Этот уровень включает в себя конкретную информацию, которая отличает одну площадку от другой, например сведения о местоположении, датах проведения исследований, ответственном персонале, местных обменных курсах и характеристиках популяции. Идентификаторы на этом уровне являются широкими и позволяют получать общее представление об исследовательском ландшафте. Под уровнем площадки находится уровень сеанса. Указанный уровень обеспечивает более четкую классификацию и важен для документирования хронологического хода исследования. Он может представлять конкретные этапы проекта или серию наблюдений. Подробная информация на уровне сеанса включает в себя конкретные проведенные эксперименты, временные рамки, задействуемые методики и процедуры, которым подвергаются испытуемые. Он служит связующим звеном, соединяющим всеобъемлющий
164  Документирование охват на уровне площадки с подробной направленностью на последующем уровне испытуемых. Наиболее детализированным уровнем в иерархии является уровень испытуемых. Указанный уровень относится к отдельным испытуемым или подразделениям исследования, таким как участники исследования или конкретные экспериментальные образцы. Каждому испытуемому присваивается уникальный идентификатор с целью обеспечения точного отслеживания и анализа. Уровень испытуемых включает подробные данные по каждому разделу, включая демографическую информацию в исследованиях на людях, конкретные характеристики образцов в лабораторных исследованиях и подробные наблюдения в полевых исследованиях. Испытуемый однозначно идентифицируется по связанной с ним площадке, сеансу и номеру испытуемого. Рис. 17.2  Пример маркировки Такая структурированная иерархия эффективно организовывает все материалы и системы, обеспечивая надежную основу для всего проекта. Помечая каждый документ уникальным идентификатором, обеспечивается способность легко вспоминать нужные материалы в случае путаницы. Вдобавок включение важной информации в этикетки, такой как идентификатор, количество участников, выплаты, время и дата, к примеру, помогает быстро находить важные данные и обращаться к ним. Например, пакет сеанса, содержащий все материалы участников с надлежащей маркировкой, может упростить процесс. Хотя от этой структуры допускаются отклонения, решающее значение для поддержания продуктивной и организованной работы имеет отыскание системы, удовлетворяющей конкретным исследовательским потребностям. Настоятельно рекомендуется рассмотреть комплект облачных инструментов Google Пространство для работы (или Google Workspace), поскольку его продукты широко используются и понятны пользователям. Google Таблицы и Google Диск обеспечивают бесперебойное взаимодействие, позволяя создавать перекрестные ссылки между документами и папками. Google Диск поддерживает создание надежной структуры папок, а Google Документы предоставляет отличные инструменты для совместной работы. Google Таблицы предлагает широкие возможности для ввода и первичной обработки данных, позволяя поддерживать базу данных в рамках платформы. Данная служба
Физическая и электронная документация  165 также обеспечивает удобную загрузку данных в R через интерфейс прикладного программирования (API) (о котором пойдет речь в следующей главе). Более того, Google Таблицы можно использовать для постройки простой информационной панели, чтобы отслеживать результаты по мере поступления новых данных, что помогает эффективно мониторить потенциальные проб­ лемы. Вдобавок если вы работаете над более крупным проектом, то имеется возможность реализовать систему разрешений с целью обеспечения более качественного контроля. 17.2. Физическая и электронная документация Физическая документация является важнейшим компонентом исследований, обеспечивающим надежный и взаимоувязанный сбор данных. Следует уделять внимание структурированному форматированию и стратегическому управлению физическими документами. Ниже приведен краткий обзор передовой практики. 1. Единообразность и ясность: важно, чтобы физические документы имели единообразный формат и четко сформулированные вопросы, дабы уменьшать количество ошибок при толковании. Такая взаимо­ увязанность способствует сбору точных данных и обеспечивает единообразное понимание участниками. 2. Эффективное потребление бумаги: разумное использование бумаги помогает контролировать расходы и снижает воздействие на окружающую среду. Использование таких методов, как двусторонняя печать, и предпочтение цифровых копий, где это возможно, значительно сокращает расход бумаги. Более того, избыток бумаги может стать обременительным и затруднить обработку результатов. 3. Отслеживание соглашений об участии: присваивает уникальные идентификаторы испытуемых в формах согласия с целью эффективного отслеживания (рис. 17.2). После сеансов удобно помогает их сличать, тем самым обеспечивая соблюдение этических норм. Кроме того, включает версию опроса, чтобы облегчать поиск по ссылкам в будущем. При электронном сборе данных их хранение и маркировка в основном выполняются автоматически. Однако при сборе данных на бумажных носителях решающее значение имеет тщательная маркировка. 4. Ведение учетных записей, относящихся к конкретному сеансу: поддерживает подробные записи в течение каждого сеанса. Такая оперативная документация должна охватывать любые изменения или существенные происшествия, тем самым повышая точность и полноту сбора данных.
166  Документирование Примечание 17.2. Рекомендуется вести полевой журнал для записи наблюдений, касающихся погоды, политического климата, циклов экспериментов, площадки и других соответствующих факторов. Эффективная физическая документация имеет решающее значение для сохранения целостности и прослеживаемости исследовательских данных. После сбора данных рекомендуется сохранять изначальные источники данных для возможного уточнения в будущем. Не менее важна и электронная документация, которая защищает исследовательские данные, обеспечивая как защищенность, так и доступность. После каждого исследовательского сеанса следует незамедлительно переносить всю собранную информацию в электронную таблицу сеанса и сканировать физические документы, чтобы создавать цифровые копии. В современном цифровом мире защита данных и конфиденциальность имеют первостепенное значение для целостности исследований. Рекомендуется применять надежные стратегии защиты данных, чтобы обеспечивать защищенность собранных данных, в особенности личной информации об испытуемых. Сюда входит обезличивание данных, использование технологических решений для безопасного хранения и соблюдение законов о защите данных, в особенности при обработке информации, позволяющей устанавливать личность. Обеспечение качества имеет равнозначную важность. Следует разрабатывать комплексную стратегию обеспечения качества данных путем внедрения программ обучения для сборщиков данных с целью обеспечения точности и взаимоувязанности. Рекомендуется проводить регулярные проверки или аудиты данных с целью выявления и исправления ошибок или несостыковок. Кроме того, нужно формировать механизмы обратной связи с целью постоянного совершенствования. 17.3. Организация данных в электронных таблицах Электронные таблицы используются повсеместно, и зачастую они являются первым и единственным способом, с помощью которого люди учатся взаимодействовать с данными. И хотя с их помощью можно делать практически все, что угодно, это не значит, что вы должны создавать симулятор американских горок в Excel1. Здесь мы сосредоточимся на организации электронных таблиц для ввода и хранения данных с целью уменьшения количества ошибок и упрощения последующего анализа. Эта работа в значительной степени основана на моем личном опыте и советах Бромана и Ву [7]. 1 См. https://www.youtube.com/watch?v=IrVA1BBHFHw.
Организация данных в электронных таблицах  167 17.3.1. Организация электронных таблиц Взаимоувязанность является краеугольным камнем эффективного ввода и организации данных. Крайне важно придерживаться единообразного подхода к обработке данных, чтобы впоследствии избегать необходимости в их гармонизации, отнимающей много времени. Говоря об организации и хранении данных, следует подумать о том, как они будут вводиться, передаваться и храниться. Инструмент Google Таблицы рекомендуется задействовать из-за его доступности и бесплатности, но приложение Excel или другое программное обеспечение тоже может быть эффективным. Изложенные здесь принципы применимы независимо от используемого программного обеспечения. В случае крупных наборов данных рекомендуется их распределять по нескольким листам или рабочим книгам, а не втискивать все в один лист. Такой подход предотвращает беспорядок и упрощает управление данными и их экспорт. Надо помнить, что на одном листе не следует размещать несколько таблиц, так как это усложняет работу с данными и их экспорт. Данные должны быть организованы в упорядоченном прямоугольном формате, с использованием строк для испытуемых и столбцов для переменных. Заголовок, или колонтитул (первая строка), должен содержать имена переменных – его следует ограничить одной строкой; в противном случае он будет запутывать и затруднять работу. Если вы хотите улучшить навигацию, то рекомендуется обратить внимание на форматирование. Надо избегать использования форматирования для передачи ключевой информации; вместо этого лучше выбирать отдельные столбцы. В том, что касается именования переменных, в особенности в случаях, когда их много, важно придерживаться следующих ниже рекомендаций. 1. Избегать пробелов: в именах переменных рекомендуется всегда использовать символы подчеркивания (_) вместо пробелов, следуя стилю tidyverse. Например, использовать temperature_15_minutes вместо temperature 15 minutes. 2. Подбирать описательные и лаконичные имена: рекомендуется выбирать короткие и информативные имена. Например, имя tempc_15_min предпочтительнее, чем temperature_15_minutes, поскольку оно является кратким и указывает единицу измерения (Цельсий). Хотя предпочтение отдается коротким именам, при необходимости не нужно бояться использовать более длинные. 3. Поддерживать единообразие во всех файлах: рекомендуется единообразно использовать одинаковые имена переменных во всех файлах (например, всегда использовать имя tempc вместо чередования таких вариантов, как temp_room_c и temp). 4. Избегать специальных символов: рекомендуется воздерживаться от использования эмодзи, латексных символов или других специальных символов, например ~, !, #, $, %, ˆ, &, *, (, \, так как они могут приводить к ошибкам.
168  Документирование 5. Структурировать имена для удобства анализа: рекомендуется начинать имена переменных с кода раздела (например, q#_ для обозначения номера вопроса, p_ для обозначения вопросов о личности, s_ для обозначения вопросов о статусе), чтобы облегчать последующий анализ (потом будет легко выбрать все вопросы о личности select(starts_ with("p_"))). Для столбцов комментариев следует добавлять _comment, чтобы легко исключать их при необходимости. Все вышеприведенные рекомендации применимы и к именам файлов! Кроме того, полезно назначать имена файлам в соответствии с предпочтительным упорядочиванием. Например, если даты играют важную роль для сор­тировки, то будет лучше указывать формат год-месяц-день в начале имени файла. При работе с числовыми последовательностями следует использовать начальные нули с целью обеспечения правильного порядка следования, например 004 < 015 < 030 < 200, а не 15 < 200 < 30 < 4. Однако будьте осторожны при последовательном именовании файлов, поскольку переименовать несколько файлов, чтобы добавить новые элементы или изменить их порядок следования, будет крайне сложно. Таблица 17.1. Примеры правильных и неправильных имен файлов Неправильно table 1.tex My Thesis.docx Правильно tbl01_temperature-vs-dictator.tex 2023-12-24_thesis-for-review.docx При настройке электронных таблиц важно отделять таблицы ввода данных от таблиц окончательных данных. Следует избегать выполнения вычислений в файлах сырых данных из-за возможных проблем с округлением и непредвиденных ошибок в программах для работы с электронными таблицами. Первичный файл должен содержать только данные, а любые вычисления или графический анализ нужно выполнять на копии файла. С целью обеспечения точности ввода данных рекомендуется использовать инструменты валидации. Обычно достаточно стандартных возможностей валидации, но в интернете доступны дополнительные методы. Валидация должна применяться к каждому столбцу! Наконец, если к файлам имеют доступ несколько человек, то разумно распределить права доступа. Следует защитить ячейки, которые не нужно изменять, и регулярно создавать резервные копии. Потратив время на настройку этих мер защиты, вы сэкономите недели на возможную доработку. 17.3.2. Ввод данных После того как вы сформируете свою организационную структуру, следующим шагом будет ввод данных. Здесь мы обсудим рекомендации по регист­ рации данных.
Организация данных в электронных таблицах  169 1. Единообразные коды: рекомендуется использовать взаимоувязанную систему кодирования для каждой категории. Например, при классификации по полу надо выбрать один ярлык (например, «Муж») и его придерживаться. Следует избегать таких вариантов, как «М», «муж» или «МУЖ». 2. Фиксированный код для пропущенных значений: рекомендуется установить стандартный символ или код для пропущенных данных, например «NA» или дефис. Следует избегать использования цифр (например, 77 или 999) для обозначения пропущенных числовых данных, и не нужно оставлять ячейки пустыми или использовать пробелы, так как их можно легко проглядеть. 3. Единообразные идентификаторы испытуемых: во всех записях рекомендуется задействовать взаимоувязанный формат идентификаторов испытуемых. Неплохим стандартом будет составной ключ, такой как site_id_session_n_subject_n. 4. Взаимоувязанный формат дат: во избежание путаницы (например, ошибочное принятие 2023/05/10 за 10 мая либо за 5 октября) рекомендуется использовать единообразный формат дат. Стандарт ISO 8601 (ГГГГ-ММ-ДД) является общепризнанным и устраняет двусмысленность. При работе с электронными таблицами, такими как Excel или Google Таблицы, которые могут автоматически форматировать даты, следует быть внимательными; во избежание этой проблемы рекомендуется задать для столбцов текстовые типы данных. 5. Никаких дополнительных пробелов: рекомендуется обратить внимание на дополнительные пробелы в ячейках. Они могут приводить к расхождениям, например между «муж» и «муж ». 6. Заполненные ячейки: следует проверять, чтобы все ячейки были заполнены. Рекомендуется использовать стандартный код для пропущенных данных, чтобы отличать подлинные пропущенные данные от непреднамеренных пробелов. Такая наглядность помогает понимать, отсутствуют данные или нет, были они пропущены из-за ошибки ввода либо имеют другой смысл. 7. По одному значению данных на ячейку: рекомендуется придерживаться принципа «упорядоченности данных», следя за тем, чтобы каждая ячейка содержала только одну единицу информации. Если столбец содержит несколько значений, то следует рассмотреть возможность его разбивки на отдельные столбцы. С заметками или комментариями надо поступать аналогичным образом, то есть хранить в отдельных столбцах, а не помещать их в ячейки с данными. Следует избегать использования стилей шрифта или цветности для передачи информации; вместо этого такие данные лучше кодировать в отдельных, четко обозначенных столбцах. 8. Взаимоувязанная терминология в комментариях: при добавлении комментариев рекомендуется использовать единообразную терминологию с целью облегчения поиска и категоризации.
170  Документирование 9. Никаких объединенных ячеек: при подготовке к загрузке данных следует разъединять все объединенные ячейки, чтобы не создавать пустые ячейки, которые могут усложнять обработку и анализ данных. После того как окончательно отработаете структуру и разберетесь в своих данных, рекомендуется создать словарь данных. Он должен включать следующие ниже элементы:   имя переменной;   описание переменной;   опционально, ее категорию, название для визуализации и возможные значения. Таблица 17.2. Пример словаря данных Категория Переменная Личность Статус Название Значения Описание для визуализации q1_p_agreeable доброжелательность 1−5 Оценка доброжелательности q2_s_perception самовосприятие 1−5 Самооценка социального статуса 17.4. Администрирование Процесс администрирования играет ключевую роль в формировании эффективности, целостности и общего успеха исследований. Основой успеха является ряд четко определенных протоколов и процедур, которые имеют решающее значение для поддержания взаимоувязанности и надежности сбора данных. Ключевые элементы этого подхода включают следующее: 1. Скрипт экспериментатора: рекомендуется разработать подробный скрипт для экспериментаторов, в котором будут изложены правила общения, протоколы взаимодействия участников и ответы на возможные запросы. В указанном скрипте особое внимание должно уделяться поддержанию свободы воли участников и эффективному реагированию на непредвиденные обстоятельства. 2. Соблюдение процедур: в день сбора данных крайне важно строго следовать установленным процедурам, чтобы обеспечивать единообразие и эффективность всех сеансов. 3. Планирование с учетом непредвиденных обстоятельств: рекомендуется подготовиться к неожиданным сценариям с помощью комплексных планов действий в чрезвычайных ситуациях с целью защиты от их негативного влияния на целостность данных. 4. Административная блок-схема: рекомендуется использовать блоксхему, в которой четко будет прописан процесс исследования, от прибытия участников до ввода данных, с указанием ключевых этапов и точек принятия решений.
Финансовая отчетность в научных исследованиях  171 5. Обратная связь и этические соображения: рекомендуется включить механизмы обратной связи с целью постоянного совершенствования и обеспечить, чтобы вся административная работа не выходила за пределы этических стандартов, включая конфиденциальность участников и данных. 6. Обучение коллектива: рекомендуется проводить регулярные тренинги и практические занятия для исследовательской группы, чтобы обес­ печивать владение исследовательскими процедурами и протоколами. Хотя стратегии взятия выборок и маркетинга в идеале должны быть включены в план проекта, они часто принимаются на месте. Поэтому важно документально подтверждать стратегию взятия выборки, которую вы использовали, будь то случайная выборка, стратифицированная, по методу «снежного кома», добровольческая или какая-либо другая. Вдобавок следует зарегист­ рировать маркетинговые инструменты, используемые для привлечения участников и планирования сеансов. Рекомендуется обеспечить, чтобы процесс регистрации на мероприятия был простым и стандартизированным, при этом рекомендуется использовать внешние службы, такие как Eventbrite. Если принять на вооружение перечисленные выше упрощенные админист­ ративные методы, то исследовательские проекты могут значительно улучшиться с точки зрения операционной эффективности, взаимоувязанности в сборе данных и соблюдения этических принципов, что приведет к получению более надежных и обоснованных результатов исследований. В качестве примера административного процесса (рис. 17.3) приведена версия, которая использовалась в эксперименте, созданном в Lucid Chart. Хотя она может показаться запутанной, она все же помогает понять необходимые шаги и более эффективно делиться ими с другими. 17.5. Финансовая отчетность в научных исследованиях Эффективная финансовая отчетность в научных исследованиях играет такую же важную роль, как и в управлении стартапом. Она предусматривает тщательное ведение бухгалтерских книг и обеспечение финансовой прозрачности. Ключевые образцы практики включают следующее: 1. Документирование транзакций: рекомендуется тщательно документировать все поступления по транзакциям. Это предусматривает ведение подробного учета каждой финансовой транзакции, связанной с исследованиями. 2. Ведение цифровых учетных записей: рекомендуется использовать Google Таблицы или аналогичный инструмент, предоставляемый вашей организацией, с целью систематического ведения учетных записей. Под цифровыми учетными записями подразумеваются подробные записи по каждой транзакции.
172  Документирование Перед первым сеансом определиться с оплатой за посещение, курсами обмена валют, компенсациями, количеством RA, а также отредактировать и перевести печатные материалы В начале дня определиться с вариантом, процедурами и временем их проведения, используя информацию из инструкции к сеансу. Установить датчики температуры в соответствующих местах. Убедиться, что все в порядке, обогреватели и датчики работают, имеется достаточное количество печатных материалов и канцелярских принадлежностей, а в помещении нет никаких дефектов Офис Процесс эксперимента Внутри аудитории Вне аудитории Нет Начать Достаточное количество участников? Подготовить пакеты с инструк­ циями Сообщить о выплатах в бэк-офис Подготовить выплаты для участников и внести итоговые данные в лист согласований Да Зарегистри­ ровать время начала, кол-во испытуемых, версию и процедуру Зарегистрировать результаты сыгранной партии, орлы/решки, выплаты по каждому участнику Пригласить участников занять свои места в аудитории Раздать бланки согласия на подписание Начать сеанс Попросить участников написать номер своего места и расписаться Предоставить инструкции попросить участников указать номер своего места Попросить участников взять бланки согласия, покинуть аудиторию в определенном порядке, оставить свои документы на своих местах и дождаться, когда назовут их номер телефона Приглашать участников по одному. Попросить их написать свое имя и поставить подпись рядом с полученной суммой, заполнить форму согласия, указать номер сеанса и оплаченную сумму. Заплатить участнику, заклеить имена стикером Предоставить инструкции по выполнению задания (см. руководство) Раздать анкеты, попросить указать номера мест Попросить заполнить анкеты (см. руководство) Зарегистри­ ровать время окончания Вернуться в аудиторию. Указать идентификатор сеанса на инструкциях и анкетах и закрепить их в убывающем порядке. Закрепить формы согласия и поместить их сверху. Написать записку со всей информацией о сеансе, поместить все в папку Сеанс завершен Ввести информацию о сеансе и реальных выплатах Внести данные инструкций в таблицы Собрать и обновить данные с датчиков температуры в конце недели или по мере необходимости Посмотреть на панель управления Рис. 17.3  Процесс администрирования 3. Облачное хранение: рекомендуется сканировать или фотографировать все квитанции и финансовые документы и закачивать изображения в облачную службу, указывая каждому файлу соответствующее записям в таблице имя ради удобства использования перекрестных ссылок. 4. Конвертация валют: рекомендуется скрупулезно регистрировать конвертации валют, в особенности при международных транзакциях, с целью обеспечения точности финансовой отчетности.
Краткий итог  173 5. Регулярные аудиты: рекомендуется проводить периодические аудиты с целью обеспечения точности и прозрачности финансовых учетных записей. 17.6. Коммуникация Эффективная коммуникация является неотъемлемой частью успеха любого эксперимента. Необходимо подготавливать подробные документы, содержащие четкие инструкции по использованию каждого компонента системы эксперимента. Эти документы должны включать: 1. Инструкции по процедурам: пошаговое описание процессов взятия выборок, администрирования, сбора данных и обработки в понятной и сжатой форме. 2. Учебные материалы: практические демонстрации процедур, которые помогут сотрудникам на местах ознакомиться с процессами до начала сбора данных. 3. Справочные руководства: краткие справочные материалы, в которых кратко излагаются ключевые моменты из руководств по процедурам и учебных материалов. 4. Руководство по вводу данных: содержит четкие инструкции о том, как вводить данные в электронную систему. 5. Политику защиты данных: объясняет способы и процедуры защиты персональных данных. 6. Процедуры контроля качества: очерчивает стратегии обеспечения качества собранных данных. 7. Механизмы обратной связи: объясняет то, как будут собираться отзывы и использоваться для улучшения будущих исследований. Благодаря легкодоступности этих документов для сотрудников на местах ваш эксперимент будет проходить гладко, обеспечивая получение высококачественных, воспроизводимых данных. Хорошо задокументированный эксперимент является ключом к успешному исследованию. Придерживаясь этих рекомендаций, вы сможете обеспечивать воспроизводимость, отслеживаемость и высокое качество результатов вашего исследования. 17.7. Краткий итог В этой главе подчеркивается важность всестороннего документирования в исследованиях с целью обеспечения взаимоувязанности в собираемых данных и соблюдения процедур. Ключевые принципы включают отслежи-
174  Документирование ваемость, доступность, единообразное форматирование и защищенность. Документация должна соответствовать иерархической структуре, охватывающей уровни проекта, площадки, сеанса и испытуемых. Практические советы охватывают как физическую, так и электронную документацию, уделяя особое внимание защите данных и контролю качества. Решающее значение имеют правильная организация данных в электронных таблицах, а также тщательное документирование деятельности на местах, администрирования и финансов. Эффективная коммуникация и обучение необходимы для обеспечения высокого качества и воспроизводимости результатов исследований. В следующей главе будут обследованы инструменты, которые можно использовать для проведения опросов, рассмотрены API-интерфейсы и способы их применения для извлечения данных из интернета.
Глава 18 Интерфейсы прикладного программирования Интерфейсы прикладного программирования (API) являются важными инст­ рументами для современного анализа данных, обеспечивая бесперебойное взаимодействие с серверами с целью эффективного извлечения данных и манипулирования ими. В этой главе будут рассмотрены основы API, вы научитесь создавать простые запросы к API и обследуете способы их применения на языке R. 18.1. Основы API Что такое интерфейс прикладного программирования? Давайте рассмотрим такую аналогию: когда вы заходите в ресторан, вы садитесь и заказываете блюда из меню. Вы не идете на кухню, чтобы проинструктировать шефповара; это было бы хаотично и неэффективно. Вместо этого ваш заказ будет доставлен официантом. В приведенной аналогии вы – клиент, кухня – это сервер, ваш заказ – это запрос, приготовленное блюдо – это ответ, а официант – это API. Подобно официанту, который знает, как принимать заказ, относить его на кухню и обслуживать вас, API предписывает то, как делать запросы, какие запросы являются допустимыми, как доставляются ответы и в каком формате. Официант защищает вас от сложностей кухни и высокой температуры. И точно так же API защищает вас от сложностей серверных операций. Вам не нужно разбираться в процессе приготовления блюд шеф-поваром; вам просто нужно передать свой заказ официанту и дождаться заказанного блюда. По аналогии с этим использование API не требует от вас понимания серверных процедур; вам просто нужно правильно сформулировать запрос и обработать полученный ответ. Взаимодействие с API предусматривает отправку запроса с необходимыми данными. Вот несколько типов запросов, которые можно делать:
176  Интерфейсы прикладного программирования 1. GET: это все равно, что просить официанта заказать блюдо. Этот метод предусматривает запрос данных без внесения изменений. В контексте API запрос методом GET извлекает информацию с сервера. 2. POST: это сродни добавлению нового блюда в меню. Этот метод преду­ сматривает предоставление API-интерфейсу конкретных инструкций, чтобы попросить сервер добавить новый элемент. С точки зрения API, запрос методом POST передает данные на сервер, генерируя новую запись. 3. PUT: предположим, что вы хотите поменять свой заказ с бургера на пиццу. Это действие соответствует запросу методом PUT, который обновляет всю запись. 4. PATCH: предположим, что вместо замены бургера вы просто хотите заменить сыр с американского на швейцарский. Это действие соответствует запросу методом PATCH, используемому для обновления определенной части существующей информации. 5. DELETE: представьте, что вы отменяете и удаляете элемент из своего заказа после получения блюда. Это действие совпадает с запросом методом DELETE, который удаляет существующие данные с сервера. Перечисленные выше базовые типы HTTP-запросов аналогичны взаимодействию с официантом в ресторане. Для правильного оформления заказа необходимо четкое взаимопонимание с официантом. При работе с API происходит аналогичное – для получения требуемых данных или выполнения желаемой операции решающее значение имеет использование соответствующего типа запроса. По сути, запрос к API аналогичен скачиванию браузером веб-страницы сервера при открытии ссылки. Например, проследовав по ссылке: https:// api.census.gov/data/2021/acs/acs5?get=NAME,group(B01001)&for=us:1, можно доставить данные переписи населения США за 2021 год из Бюро переписи населения. API унифицированных указателей ресурсов (URL-адресов) построен в структурированном формате, состоящем из нескольких компонентов. Протокол (например, https://) указывает на то, как осуществляется безопасная передача данных. Базовый URL-адрес (например, api.census.gov) указывает на главный адрес сервера API. Путь (например, /data/2021/acs/acs5) указывает на ресурс, к которому осуществляется доступ, в данном случае год, и конкретный набор данных. Наконец, параметры запроса (например, ?get=NAME, group(B01001)&for=us:1) предоставляют серверу дополнительные инструкции, структурированные в виде пар ключ=значение и отделенные символом &. Вмес­ те эти компоненты образуют полноценный унифицированный указатель ресурса, или URL-адрес. Обычно для взаимодействия с API используется не текстовая ссылка, а интерфейс. Их существует масса, но я неравнодушен к инструменту командной оболочки HTTPie1, который также предоставляет онлайновые и локальные приложения. Следуйте инструкциям по установке на его веб-сайте. 1 См. https://httpie.io/cli.
Основы API  177 Независимо от того, что вы делаете, будь то использование https в своем терминале или переход на веб-сайт HTTPie, вы легко сможете выполнить свой первый запрос к API. Приведенная ниже команда вернет заголовок с информацией и ответное сообщение, отформатированное в виде строкового литерала JSON: https httpie.io/hello { "ahoy": [ "Hello, World! Thank you for trying out HTTPie", "We hope this will become a friendship" ], "links": { "discord": "https://httpie.io/discord", "github": "https://github.com/httpie", "homepage": "https://httpie.io", "twitter": "https://twitter.com/httpie" } } Примечание 18.1. Объектная нотация JavaScript (JavaScript Object Notation, аббр. JSON) – это простой, удобочитаемый формат данных, легко разбираемый и генерируемый как людьми, так и машинами. Его структура состоит из пар ключ-значение и массивов, что делает его широко применимым в вебинтерфейсах и для обмена данными. Запрос к API в основном состоит из трех компонентов: конечной точки запроса, заголовка и тела. 1. Конечная точка API: относится к определенному URL-адресу или унифицированному идентификатору ресурса (URI) веб-службы, которая служит точкой доступа для выполнения запросов и получения ответов от API. 2. Заголовок запроса: содержит дополнительные сведения о запросе, такие как метаданные или инструкции сервера. Он включает в себя такую информацию, как метод HTTP, тип содержимого, учетные данные для аутентификации и многое другое. Заголовки предоставляют контекст или управляют поведением запроса API. 3. Тело запроса: содержит любые данные или параметры, которые необходимо отправить на сервер вместе с запросом к API. В основном используется для таких методов, как POST, PUT или PATCH. Тело может содержать различные форматы данных, такие как JSON, XML, данные формы или двоичные данные, в зависимости от требований API. Вместе заголовок и текст запроса обеспечивают эффективную связь с API, указывая необходимую информацию, желаемое действие, отправляемые данные и любые дополнительные инструкции или детали аутентификации. Давайте добавим заголовок и текст к запросу: https POST pie.dev/post X-API-Token:123 name=John
178  Интерфейсы прикладного программирования В данном случае для отправки данных в конечную точку API pie.dev/post используется метод POST, добавляя заголовок X-API-Token:123 и указывая в теле значение поля name как John. Вы получите ответ в формате JSON с подробной информацией об успешном выполнении запроса методом POST! Если это кажется вам сложным или вы предпочитаете более удобный способ взаимодействия с API, то рекомендую использовать приложение HTTPie или службу наподобие PostMan, которая предоставляет графический интерфейс. 18.2. Использование API на языке R В среде языка R API-интерфейсы открывают доступ к огромному количеству интересных наборов данных для проектов по анализу данных. Давайте рассмотрим реализацию API на языке R с помощью пакета httr2. # install.packages("httr2") library(httr2) Начнем взаимодействовать с API с помощью функции request(), чтобы построить запрос, и функции req_perform(), чтобы отправить запрос, из пакета httr2. Мы будем извлекать данные из API Gutendex1, предоставляющего доступ к метаданным электронных книг Project Gutenberg2. Следующий ниже исходный код извлекает данные из API, в частности об авторах, живших до 500 г. до н. э. (?author_year_end=-499): # Создать запрос к базовому URL-адресу req <- request("https://gutendex.com/books") |> req_url_query(author_year_end = -499) # Добавить параметр запроса req_dry_run(req) # Показать отправляемый запрос (холостой прогон) #> #> #> #> #> GET /books?author_year_end=-499 HTTP/1.1 Host: gutendex.com User-Agent: httr2/1.0.0 r-curl/5.2.0 libcurl/8.6.0 Accept: */* Accept-Encoding: deflate, gzip res <- req |> req_perform() # Выполнить запрос Функция request() инициализирует новый объект-запрос, а функция req_ url_query() добавляет параметры запроса к URL-адресу. Функция req_dry_ run() показывает отправляемый запрос, не отправляя его на самом деле. Функция req_perform() отправляет HTTP-запрос методом GET и сохраняет 1 2 См. https://gutendex.com/. См. https://www.gutenberg.org/.
Использование API на языке R  179 ответ API в переменной res. Давайте проинспектируем ответ, распечатав объект res: print(res) #> #> #> #> #> <httr2_response> GET https://gutendex.com/books/?author_year_end=-499 Status: 200 OK Content-Type: application/json Body: In memory (34502 bytes) Следующим шагом будет структурно-синтаксический разбор ответа, полученного в формате JSON: data <- res |> resp_body_json() Функция resp_body_json() непосредственно выполняет разбор содержимого ответа, конвертируя в структурированный объект языка R, такой как список или кадр данных. Примечание 18.2. Рекомендуется использовать функцию glimpse(), чтобы заглядывать в структуру ответа. Однако следует учитывать, что иногда ответ может быть очень длинным, как в данном случае, поэтому он не был включен. Просмотрите данные, обратившись к их элементам. Например, можно вывести на экран следующие названия книг: head(purrr::map_chr(data$results, "title"), n = 5) #> #> #> #> #> #> [1] "The Iliad" [2] "The Odyssey: Rendered into English prose for the use of those who cannot read the original" [3] "La Odisea" [4] "The Iliad" [5] "The Odyssey" Вуаля! Вы успешно выполнили запрос к API на языке R и получили данные для дальнейшего обследования. В целях тонкой настройки запроса к API можно использовать дополнительные параметры запроса, чтобы сориентировать поиск в отношении авторов, живших до 500 г. до н. э., и их произведений в стиле эпической поэзии в переводе на французский язык. Этого можно достичь, добавив topic = "Epic Poetry" и languages = "fr" в заголовок URL-запроса, аналогично тому, как добавлялся параметр author_year_end = -499. В некоторых случаях может потребоваться запрос методом POST, в особенности при отправке тела запроса. В пакете httr2 этого можно добиться, включив тело запроса с использованием семейства функций req_body_*(), таких как req_body_json(req, list(key1 = "значение1", key2 = "значение2")), или применив функцию req_method() для указания другого метода HTTP. В от-
180  Интерфейсы прикладного программирования ношении информации о конкретных требованиях и доступных заголовках рекомендуется всегда обращаться к документации по API. Получив некоторое представление о том, что такое API-интерфейсы и как с ними взаимодействовать, теперь давайте рассмотрим разные пакеты, которые позволяют взаимодействовать с такими полезными службами, как Qualtrics, Google Таблицы и OpenAI. 18.3. API системы Qualtrics Вместо того чтобы всякий раз, когда требуется обновить результаты опроса, скачивать данные через Qualtrics, можно загружать данные с помощью API Qualtrics. Полное руководство можно получить, обратившись к документации пакета и виньеткам1. Если ваш университет предоставляет доступ к Qualtrics, то вам, возможно, все-таки потребуется отдельно запросить доступ к API у ИТ-служб. Сначала нужно установить пакет qualtRics. # install.packages("qualtRics") library("qualtRics") Пакет содержит три ключевые функции:   функция all_surveys() показывает опросы, к которым можно получить доступ;   функция fetch_survey() загружает опрос;   функция read_survey() читает CSV-файлы, скачанные вами вручную из Qualtrics. Он также содержит ряд вспомогательных функций, в том числе следующие:   функция qualtrics_api_credentials() сохраняет ваш API-ключ и базовый URL-адрес в переменных среды;   функция survey_questions() извлекает кадр данных, содержащий вопросы и идентификаторы вопросов из опроса;   функция extract_colmap() извлекает аналогичный кадр данных с более подробным отображением столбцов в названия;   функция metadata() извлекает метаданные о вашем опросе, например о вопросах, ходе опроса и количестве ответов. Примечание 18.3. Экспортировать можно только те опросы, которые принадлежат вам или на которые у вас есть административные права. Если вы получили доступ к API, то теперь можете к нему подключиться. Для получения ключа API (api_key) и базового URL-адреса (base_url) надо перейти на домашнюю страницу Qualtrics. Затем в Account Settings (На1 См. https://cran.r-project.org/web/packages/qualtRics.
API системы Qualtrics  181 стройки учетной записи) → Qualtrics IDs (Идентификаторы Qualtrics) (для более старой версии). В разделе API надо кликнуть по Generate Token (Сгенерировать токен), и вам будет выдан токен. Скопируйте его и введите свой ключ API ("YOUR_API_ KEY"). Затем взгляните на модуль User (Пользователь), скопируйте Datacenter ID (Идентификатор центра обработки данных) и добавьте .qualtrics.com пос­ле него. Ваш base_url должен выглядеть примерно так: lad2.qualtrics.com. qualtrics_api_credentials( api_key = "YOUR_API_KEY", base_url = "YOUR_BASE_URL", install = TRUE, # overwrite = TRUE # Если нужно обновить свои учетные данные ) После того как qualtrics_api_credintials сохранит ваши учетные данные, вы сможете воспользоваться функцией all_surveys(), чтобы доставить информацию о своих опросах. head(all_surveys(), 5) #> #> #> #> #> #> #> #> # A tibble: 9 x 6 id <chr> 1 SV_0rearXjH2Ri6umq 2 SV_2gWVWLn2vCCDJGu 3 SV_3h0HPHQbJStqb8a 4 SV_3Q011O6gNqwn1Nc 5 SV_4YDoTFLN61nKecS name <chr> Student Satisfa~ Luvuyo Pilot (USA) – G~ Pen Experiment Pen_Showcase ownerId <chr> UR_2tz~ UR_2tz~ UR_2tz~ UR_2tz~ UR_2tz~ lastModified <chr> 2023-01-29T~ 2022-05-03T~ 2022-05-03T~ 2022-12-09T~ 2023-01-29T~ creationDate <chr> 2023-01-17T~ 2022-05-03T~ 2022-05-03T~ 2022-12-06T~ 2023-01-29T~ isActive <lgl> FALSE FALSE FALSE FALSE TRUE Выбрав нужную анкету, не нее можно будет ссылаться, используя id. По желанию можно скачать набор данных повторно, указав force_request = TRUE; в противном случае будут загружены ранее скачанные и сохраненные данные. Скорее всего, в наборе данных будет много столбцов; все зависит от количества вопросов. survey_data <- fetch_survey( surveyID = "SV_bJIs8lwz4CfAAgS", verbose = FALSE, force_request = TRUE ) survey_data %>% select(StartDate, Duration (in seconds), Finished, Gender, offer, decision...81, participantRole) %>% glimpse() #> Rows: 22 #> Columns: 89 #> $ StartDate <dttm> 2023-02-07 16:00:52, 2023-02-07 16:01:17, 2~
182  Интерфейсы прикладного программирования #> $ EndDate #> $ Status #> $ IPAddress <dttm> 2023-02-07 16:04:08, 2023-02-07 16:04:08, 2~ <chr> "IP Address", "IP Address", "IP Address", "I~ <chr> "138.202.129.171", "138.202.129.164", "138.2~ Если требуется просмотреть текст вопросов, то можно воспользоваться функцией survey_questions(). head(survey_questions(surveyID = "SV_bJIs8lwz4CfAAgS"), n = 5) #> #> #> #> #> #> #> #> # A tibble: 5 x 4 qid qname <chr> <chr> 1 QID25 Introduction 2 QID26 Consent 3 QID21 Gender 4 QID23 Name 5 QID22 Competitive question <chr> "Welcome to the <strong>University of San F~ "Do you agree to participate in the survey?" "What is your gender" "What is your Name?" "Would you consider yourself competitive?" force_resp <lgl> FALSE TRUE TRUE FALSE FALSE 18.4. Интеграция служб Google со средой языка R В этом разделе будет обследована интеграция служб Google с R с использованием универсальности инструментов Google с целью расширения возможностей по сбору и анализу данных. Google Таблицы представляет собой универсальный и удобный облачный инструмент, который особенно эффективен для хранения данных, собранных с помощью инструмента Google Формы. Это отличное программное решение для ввода данных в проектах, связанных со сбором физических данных. Пакет googlesheets4 на языке R взаимодействует с API Google Таблицы, предлагая целый ряд функций аналитикам и исследователям данных. Вот несколько распространенных сценариев: 1. Ввод данных: данные часто вводятся в Google Таблицы разными людьми благодаря совместной работе. Пакет googlesheets4 позволяет извлекать эти данные непосредственно в среде языка R. 2. Анализ данных в реальном времени: если данные постоянно обновляются, то пакет googlesheets4 позволяет проводить анализ в реальном времени, получая доступ к самым свежим данным. 3. Предоставление отчетов о данных: результаты анализа или предсказания моделей могут быть записаны в Google Таблицы, делая их доступными для заинтересованных сторон, не имеющих технического образования. 4. Коллективное использование данных: инструмент Google Таблицы упрощает обмен данными. К вашим данным можно обращаться из любого места и в любое время.
Интеграция служб Google со средой языка R  183 Пакет gargle упрощает аутентификацию с помощью API Google и безопасно управляет токенами аутентификации. Он используется всеми пакетами R, взаимодействующими со службами Google. Использование пакета gargle повышает эффективность и защищенность рабочего процесса за счет надежного хранения токенов и упрощения повторной аутентификации в будущих сеансах. options(gargle_oauth_cache = ".secrets") googlesheets4::gs4_auth() list.files(".secrets/") gs4_auth(cache = ".secrets", email="name@mail.com") Примечание 18.4. Не забудьте добавить папку .secrets в файл .gitignore! Для извлечения данных из Google Таблицы в R используется функция read_ sheet(). При вызове нужно указать URL-адрес или идентификатор документа и название конкретного листа. library(googlesheets4) url <- "https://docs.google.com/spreadsheets/d/your_spreadsheet_id_here" data <- read_sheet(url, sheet = "Your Sheet Name") head(data) Запись данных обратно в Google Таблицы осуществляется также просто, при помощи функции write_sheet(). data_to_write <- data.frame( column1 = c("Data1", "Data2"), column2 = c("Data3", "Data4") ) write_sheet(data = data_to_write, ss = url, sheet = "Your Sheet Name") Пакет googledrive на языке R позволяет взаимодействовать с Google Диском, упрощая чтение/запись файлов и управление ими. library(googledrive) drive_auth(cache = ".secrets") print(drive_ls()) file <- drive_get(path = "Your File Name") data <- read_csv(drive_download(file, overwrite = TRUE)) Для того чтобы записать файлы на Google Диск, надо сохранить файл локально, а затем закачать его в облако с помощью функции drive_upload(): data_to_write <- data.frame( column1 = c("Data1", "Data2"), column2 = c("Data3", "Data4") )
184  Интерфейсы прикладного программирования write.csv(data_to_write, "data_to_write.csv") drive_upload("data_to_write.csv", path = "FolderName/data_to_write.csv") Примечание 18.5. На вашем компьютере также может быть папка Google Диск, и писать/читать файлы можно просто из нее. Не забывайте ответственно относиться к своим файлам, в особенности к тем, которые содержат конфиденциальные данные. Многочисленные службы Google, такие как Google Карты, Google Планета Земля, Google Облако и другие, легко доступны из R. Быстрый онлайновый поиск позволит найти различные ресурсы для ваших проектов, и, скорее всего, уже существующий пакет R упростит вам доступ. 18.5. API OpenAI На момент публикации в R появилось гораздо больше возможностей для использования больших языковых моделей (Large Language Model, аббр. LLM), включая elmer, mall, tidychatmodels и gander. Было бы преступлением не показать, как использовать API OpenAI внутри R. Хотя нужно признать, что на языке Python пакеты реализованы полнее и во всех отношениях лучше, все же рекомендуется посмотреть, что же можно делать на языке R. Пакет openai на языке R служит оболочкой для API сервисов OpenAI и включает в себя поддержку различных конечных точек, таких как модели, завершения фраз, чат, правки, изображения, векторные вложения, аудио, файлы, тонкие настройки и модерации. # install.packages("openai") library("openai") Примечание 18.6. Ознакомьтесь с официальной документацией OpenAI – она не слишком техническая и стоит вашего времени. Для получения доступа к API OpenAI надо иметь ключ API. Для начала зарегистрируйтесь в OpenAI API по адресу https://openai.com/api/. После регистрации и входа в систему надо перейти по адресу https://platform.openai. com. Затем зайти в Personal (Личный кабинет) → View API keys (Просмот­ реть ключи API) и кликнуть по зеленой кнопке Copy (Скопировать), чтобы скопировать ключ. Пакет будет искать OPENAI_API_KEY в переменных среды. Для того чтобы задать его значение в качестве глобальной переменной среды, надо исполнить следующую ниже команду, заменив YOUR_KEY на фактический ключ: Sys.setenv( OPENAI_API_KEY = 'YOUR_KEY' )
API OpenAI  185 Примечание 18.7. При использовании GitHub следует указать ключ в файле .Renviron и добавить его в свой файл .gitignore, чтобы сохранить ключ в безопас­ности. С помощью GPT-4 можно пользоваться широким спектром функциональностей, таких как рецензирование, классифицирование и редактирование текста. Вот как сгенерировать завершение чата1: chat <- create_chat_completion( # Задать используемую модель model = "gpt-4o", # Передать список сообщений на основе ролей messages = list( list( "role" = "system", "content" = "As an expert summarizer, condense the following paragraph into → one succinct sentence." ), list( "role" = "user", "content" = "R is a programming language for statistical computing and → graphics supported by the R Core Team and the R Foundation for Statistical → Computing. Created by statisticians Ross Ihaka and Robert Gentleman, R is used → among data miners, bioinformaticians and statisticians for data analysis and → developing statistical software. The core R language is augmented by a large → number of extension packages containing reusable code and documentation." ) ) ) chat$choices$message.content #> [1] "R is a programming language developed by Ross Ihaka and Robert Gentleman, → widely used for statistical computing and graphics, enhanced by numerous → extension packages for data analysis and statistical software development." Еще можно создавать изображения на основе текстовых описаний. Вот пример генерации мультяшного персонажа в оттенках серого: image <- create_image("Frog-blossom cartoon in greyscle color", size = "256x256") download.file(image$data$url, "images/openai_image.png", mode = 'wb') 1 Завершение чата (chat completion) позволяет модели учитывать контекст предыдущих сообщений, что помогает создавать более правильные и взаимоувязанные ответы. Например, когда пользователь задает вопрос или делает комментарий, система использует завершение чата для генерации релевантного ответа, а также может поддерживать тему разговора, учитывая, что было сказано ранее. За счет этого взаимодействие становится более естественным и человекоподобным. – Прим. перев.
186  Интерфейсы прикладного программирования Рис. 18.1  Генерация изображений в OpenAI Кроме того, можно получать звуковую транскрипцию, используя модель whisper: create_translation(file = "data/whisper_demo.m4a", model = "whisper-1") #> $text #> [1] "Can you hear the whisper? Whispering?" 18.6. Краткий итог API-интерфейсы предоставляют мощный и эффективный способ взаимодействия с различными источниками данных и службами, что делает их незаменимыми для современного анализа данных. В этой главе был представлен всесторонний обзор API-интерфейсов, способов выполнения различных типов запросов к API и способов их эффективного использования на языке R. В следующей части вы познакомитесь с миром визуализации данных!
ЧАСТЬ V Презентация данных
Глава 19 Основы визуализации данных Мы вот-вот отправимся в удивительное путешествие в мир визуализации данных. Изначально эта глава не планировалась, но чем больше я думал о важности базовых психофизических концепций, их связи с конструктивным исполнением (дизайном) и визуализацией данных, тем больше чувствовал необходимость ее включить. Давайте начнем с простого вопроса: что такое визуализация данных? Визуализация данных – это графическое представление информации. Следующий вопрос: каковы цели визуализации данных? 1. Эффективная передача информации и скрытых сведений. 2. Анализ и обследование. 3. Принятие решений. Возможно, это звучит тривиально, но вся сложность состоит в том, каким образом эти цели достигаются. Главная сила визуализации данных заключается в ее способности презентовать крупные, многомерные наборы данных в сжатой, удобной для восприятия форме. У нашей памяти есть пределы, поскольку обычно мы можем удерживать в голове до 5 ± 2 вещей одновременно. Визуализации помогают сокращать и упрощать информацию. Тогда каким образом достичь уровня, когда визуализации помогают лучше понимать данные? 19.1. Восприятие Для того чтобы ответить на этот вопрос, мы начнем с того, как люди воспринимают мир, или, точнее, как наш мозг обрабатывает визуальную информацию. Понимание процессов восприятия поможет понять причину, по которой одни визуальные техники более эффективны, чем другие, и выявить присущие человеческому зрительному восприятию ограничения. Эти знания
Восприятие  189 о восприятии (или перцептивной обработке) играют важную роль в принятии конструктивных решений. Визуальное восприятие происходит в два этапа, подобно мышлению по системе 1 и системе 2 Даниэля Канемана [21]: первый этап быстрый и автоматический, а второй более медленный и обдуманный. Зрительная система человека обладает необычайной способностью мгновенно и одновременно распознавать определенные элементы, как только он видит объект, без преднамеренного внимания или сознательных усилий. Эта стадия предвнимательной обработки (или преаттентивной обработки) в первую очередь связана с непосредственным и параллельным восприятием фундаментальных визуальных атрибутов, таких как ориентация, цвет, текстура и движение [30]. Во время этой фазы визуальные данные временно сохраняются в иконической памяти, представляющей собой форму транзитного хранения, которое постоянно пополняется новыми визуальными данными. В отличие от мгновенной природы предвнимательной обработки, последующая стадия серийной обработки предусматривает более продуманный и последовательный подход к обработке визуальной информации. Она происходит медленнее, что позволяет проводить более тщательный и детальный анализ визуальных данных. На этой стадии задействуется как рабочая, так и долговременная память, что способствует усвоению новой информации с учетом существующих знаний, хранящихся в мозге. 19.1.1. Предвнимательная обработка В настоящее время мы сосредоточены на системе 1, поскольку именно она «видит» и направляет наше внимание. Любопытно, что некоторые элементы внутри визуальной сцены обрабатываются предвнимательно, без осознанного внимания, менее чем за 200−250 миллисекунд, что соответствует продолжительности движения глаз. Указанная быстрая обработка осуществляется параллельно с системой низкоуровневого визуального контроля, которая позволяет одновременно анализировать множество визуальных элементов. Предвнимательная система выполняет несколько задач.   Обнаружение мишени: точное обнаружение присутствия или отсутствия элемента-«мишени» с уникальной визуальной характеристикой внутри поля отвлекающих элементов.   Обнаружение границ: быстрое и точное обнаружение текстурной границы между двумя группами элементов, при этом все элементы в каждой группе имеют общие визуальные свойства.   Отслеживание участка: отслеживание одного или нескольких элементов с уникальным визуальным признаком по мере их перемещения во времени и пространстве.   Подсчет и оценивание: подсчет или оценивание количества элементов с уникальным визуальным признаком.
190  Основы визуализации данных Давайте рассмотрим пример со стеной чисел. Попробуйте подсчитать все случаи появления числа 2. Теперь повторите попытку, выделив число 2 полужирным. Поиск числа 2 становится намного быстрее, не правда ли? Аналогичным образом можно быстро определить наличие красного круга? Вы, вероятно, заметили его еще до того, как я попросил вас обратить на него внимание. (а) Подсчитать все двойки (b) Подсчитать все двойки (выделенные полужирным) (с) Найти красный круг Разнообразие визуальных признаков, которые можно обнаруживать, удивительно велико [15], и мы уже рассмотрели оттенок (то есть качество цвета) на примере красной точки. Ниже приведено несколько типов, которые, на мой взгляд, чаще всего используются в визуализациях: (а) Длина (b) Плотность (с) Ориентация (d) Размер Еще несколько примечательных типов – это интенсивность, кривизна, границы, пересечения и все, что связано с 3D и движением. Для того чтобы узнать о предвнимательной обработке больше, настоятельно рекомендуется ознакомиться с онлайновой версией статьи Хили1. 19.1.1.1. Принципы гештальта Принципы гештальта объясняют, как человеческий мозг воспринимает визуальные образы из сгруппированных элементов. Эти принципы охватывают такие понятия, как близость, сходство, непрерывность, замкнутость, связность и ограждение. 1 См. https://www.csc2.ncsu.edu/faculty/healey/PP/.
Восприятие  191 Близость: в ситуациях, когда объекты расположены близко друг к другу, мы часто воспринимаем их как группу Рис. 19.1  Близость Сходство: в ситуациях, когда объекты имеют схожие характеристики (цвет, форму и т. д.), мы часто воспринимаем их как группу Рис. 19.2  Сходство Ограждение: в ситуациях, когда объекты окружены рамками, мы часто воспринимаем их как группу Рис. 19.3  Ограждение Замкнутость: иногда частично открытые структуры все еще могут восприниматься как группирующая метафора (например, [..]) Рис. 19.4  Замкнутость
192  Основы визуализации данных Связность: в ситуациях, когда вы проводите кривые или линии через элементы данных, это нередко воспринимается как создание связи между ними Рис. 19.5  Связность 19.1.1.2. Иерархия признаков Несколько признаков, таких как цвет и форма, в одном изображении могут представлять несколько типов данных. Однако важно убедиться, что эти визуальные элементы не смешиваются и не скрывают данные, которые мы хотим показать. Представьте себе, что вы пытаетесь найти красное яблоко в миске, полной зеленых яблок – это легко, потому что цвет выделяется. Иногда наши глаза предпочитают один визуальный признак другому. Например, когда мы наблюдаем за формами, цвета могут отвлекать и затруднять распознавание закономерностей или шаблонов. Однако если цвета однородны, формы становятся более отчетливыми. Попробуйте определить группы точек на рис. 19.6. Какие группы вы замечаете в первую очередь? Рис. 19.6  Примеры иерархии признаков На рис. 19.6 показана иерархия признаков «оттенок» и «форма» при восприятии: a) вертикальные границы оттенков легко различимы при неизменной форме, что свидетельствует о предвнимательном обнаружении различий в оттенках; b) границы цвета и форм легко различимы человеческим глазом. Однако вы, возможно, заметили, что цвет воспринимается раньше, чем форма; c) вертикальные границы оттенков выделяются на фоне различных форм, демонстрируя, что оттенок хорошо виден, несмотря на изменения формы;
Восприятие  193 d) однако вертикальные границы форм не так легко выявлять предвнимательно на фоне случайных изменений оттенков, что подчеркивает трудности обнаружения изменений форм без пристального вни­м ания. Поэтому когда мы решаем, каким образом презентовать данные визуально, необходимо выбирать признаки, которые выделяют наиболее важную информацию. Благодаря этому мы избегаем заслонения данных, которые хотим выделить. К наиболее распространенным способам визуального кодирования чисел, от наиболее легко воспринимаемых до наименее заметных, относятся следующие ниже: 1) 2) 3) 4) 5) 6) расположение вдоль общей шкалы, оси и базовой линии; расположение вдоль нейтральных осей; длина, направление, углы относительных линий/наклона; площадь; объем, кривизна, дуги/углы внутри фигуры; цвет или затенение. Давайте рассмотрим сценарий, в котором кодируются две обособленные переменные в дискретном наборе данных, используя два отдельных визуальных свойства, обработка трех из которых более сложна, скажем цвета и формы. Например, давайте вернемся к рис. 19.6. Когда нам показывают красные квадраты, черные квадраты, красные и черные круги, будет ли наше восприятие классифицировать их на четыре отдельные группы, основанные как на цвете, так и на форме, или мы будем воспринимать их в первую очередь как две более широкие группы, разделенные по цвету (красный/ черный) и форме (квадрат/круг)? Важнейший вопрос заключается в том, как эти разные свойства взаимодействуют. Будут ли они облегчать или усложнять дифференциацию и понимание данных? Существует две категории в отношении того, как эти два свойства соотносятся:   интегральность: здесь два свойства воспринимаются как единое целое. Взаимодействие между ними таково, что они рассматриваются как единый элемент;   отделимость: в этом случае каждое свойство оценивается независимо. Зритель может легко отделить и оценить каждую характеристику без вмешательства другого. В качестве примера я подготовил четыре варианта в диапазоне от интегральности до отделимости, которые приведены на рис. 19.7. В первом примере используется цветовая система LAB, которую мы рассмотрим в нескольких главах. Она кодирует два значения по шкалам красно-зеленый (А) и сине-желтый (Б)1. Эта система настолько запутана, что выглядит случайным набором цветов (каковым она, безусловно, и является). Второй пример немного лучше, так как значения кодируются высотой и шириной прямоугольников, что создает впечатление, что существуют малые, высо1 L означает яркость (lightness), но этот параметр не используется в визуализации.
194  Основы визуализации данных кие, большие и широкие прямоугольники в виде отдельных групп. Третий пример, в котором используются форма и цвет, намного лучше, но его все равно можно рассматривать как имеющий четыре отдельные группы. Наконец, четвертый пример, в котором используются группировка и цвет, не оставляет сомнений в том, что существуют два свойства: принадлежность к группе и цвет. (а) LАB А & B (b) x-размер & y-размер (с) Форма & цвет (d) Группа & цвет Рис. 19.7  Интегральность против отделимости 19.1.1.3. Нелинейное восприятие Восприятие не является равномерно линейным. Некоторые вещи воспринимаются точно, например длина, тогда как другие, такие как истинная разница между двумя величинами, люди склонны недооценивать из-за нашей способности воспринимать соотношения. Например, после небольшой практики мы довольно хорошо сумеем оценить длины и температуры. Однако в некоторых областях мы склонны недооценивать разницу и упускать из виду соотношения – например, при сравнении яркости двух источников света удвоение интенсивности может не восприниматься как удвоение яркости. Наше восприятие приспосабливается к силе сигнала; например, глаза приспосабливаются к яркому дневному свету и темноте в комнате. Визуализация всецело касается превращения чисел в картинки. Однако цель состоит в том, чтобы пользователь мог точно транслировать эти картинки обратно в числа. Одной из сложных задач в визуализации является трансляция чисел в площади. Это не только сложно расшифровать, но и закодировать. Что мы сравниваем, когда смотрим на площади, – радиус, площадь или ощущение? Давайте рассмотрим пример. Допустим, есть три серых круга и один белый. Какой серый круг, обозначенный числом, в два раза больше белого? Рис. 19.8  Нелинейное восприятие
Восприятие  195 Как ни странно, все три варианта верны! Площадь второго круга в два раза больше площади изначального, площадь третьего круга, по-видимому, в два раза больше в соответствии с законом Стивенса (который мы обсудим чуть ниже), а радиус четвертого круга в два раза больше первого. Да, это действительно сбивает с толку! То, как мы воспринимаем пропорциональные разницы в ощущениях, не является однозначной зависимостью от результатов измерения. Именно эта идея заинтересовала Стивенса, и в 1960 году он сформулировал свой закон: s(x) = axb, где s – это ощущение, x – интенсивность признака (отношение), a – мультипликативная константа (обычно 1 или близкая к 1), а b – показатель степени. Если b > 1: переоценка. Если b < 1: недооценка. Экспериментальные результаты для b центрируются вокруг 1 для длины, 0,9 для площади и 0,7 для объема. Итак, как бы мы применили это кажущееся масштабирование на практике? Давайте рассмотрим пример, в котором мы хотим нарисовать круги разной площади. Представьте, что площадь самого большого круга в двенадцать раз больше, чем площадь самого маленького. Во избежание нашей склонности к занижению мы могли бы умножить площадь приблизительно ) ,87 ыщ Пр Нас Ощущение енн о сть (1,7 од ) ол жи те ль но ст ь( 1, 1) Дл ин а (1 ) на , или Однако важно учитывать контекст и то, действительно ли эти корректировки принесут пользу визуализации. Я не видел, чтобы кто-то применял это за пределами картографического программного обеспечения, поскольку в визуализации есть несколько областей, где невозможно избежать использования кругов. Тем не менее если бы эти изменения были внесены, то вот как это выглядело бы, используя бета из [13]. 0 ь( ад ощ Пл ,5) 0 сть ( Ярко Интенсивность Рис. 19.9  Закон Стивенса
196  Основы визуализации данных (а) Без корректировки (b) С корректировкой Рис. 19.10  Пример закона Стивенса с площадью 19.2. Визуальное кодирование Разобравшись с основами того, как быстро наши глаза и мозг обрабатывают визуализации, пришло время поговорить о визуальном кодировании и связанных с ним задачах:     превращение числовых данных в визуализации; превращение категориальных данных в визуализации; иллюстрация различий между порциями информации; иллюстрация того, как данные или информация соотносятся с контекстом. У людей есть разные типы памяти, такие как долговременная, рабочая, вербальная и зрительная, каждая из которых хранится в разных частях мозга. Наша рабочая память, которая хранит информацию временно, может удерживать только около 5 ± 2 порций информации за раз. Визуализации помогают группировать или «раскладывать» информацию по полочкам, облегчая ее обработку и запоминание. Важно, чтобы при визуализации соотносящаяся информация располагалась близко друг к другу во избежание фрагментации, когда мы обособляем то, что следует запоминать вместе. Делая так, мы помогаем людям лучше запоминать и понимать информацию. Для этого можно выделять или аннотировать важные моменты, чтобы привлекать к ним внимание. Хорошее конструктивное исполнение визуализаций помогает людям быст­ ро понимать, на что они смотрят. Речь идет не только о том, чтобы поместить числа в фигуры, но и о том, чтобы заставить эти фигуры рассказывать историю. Хорошо исполненная визуализация поможет людям легко просматривать информацию и углубляться в нее, если они того захотят.
Визуальное кодирование  197 Примечание 19.1. Цель – облегчить читателю визуализации расшифровку визуальной информации без ошибок. Разные визуальные атрибуты, такие как положение, длина, угол наклона и цвет, помогают представить пользователю данные. Некоторые атрибуты, такие как положение и длина, лучше подходят для показа точных данных, тогда как другие, такие как цвет и размер, менее точны. Важно, чтобы правильный атрибут соответствовал типу показываемых данных. Использование привычных типов графиков, интуитивно понятных цветов и форм помогает делать визуализацию яснее. Не стоит заставлять людей запоминать слишком много новых символов или длинные подписи к ним, так как это может быть утомительно. Наконец, зная, кто будет смотреть на визуализацию, легче принимать правильные решения, в результате которых визуализации будут понятными, запоминаемыми и простыми в истолковании. 19.2.1. Оценивание графиков Как оценивать графики так, чтобы не вводить аудиторию в заблуждение, а просвещать и вовлекать ее? Для этой цели было предложено несколько практических каркасов. Одной из популярных идей в области визуализации данных является соотношение объема данных и объема чернил [31], предложенное Эдвардом Тафтом. Суть этой идеи состоит в том, чтобы упростить процесс и избавиться от всего лишнего, что не помогает доносить главную мысль. Как советует Тафт, полезно «в разумных пределах стирать чернила не данных» и «в разумных пределах стирать избыточные чернила данных». Может возникать соблазн удалять слишком много, но лучше не торопиться. Просто надо доверять свое­ му внутреннему чутью в отношении того, имеет ли график по-прежнему смысл. Обсуждаемые далее рекомендации основаны на использовании чис­ тых и ясных графиков. (а) До (b) После Рис. 19.11  Пример использования соотношения «чернил данных»
198  Основы визуализации данных В работе «Рычаги для построения графиков» [11] Уэр предлагает несколько критически важных факторов, влияющих на эффективность графика. К числу таких факторов относится скорость получения первичного осмысления, которая измеряет, насколько быстро аудитория сможет усвоить ключевое сообщение из графика. Гранулярность относится к уровню детализации, презентуемому в данных графика. Дихотомия между «разведывать и объяснять» отражает, предназначена ли визуализация для интерактивного разведывательного анализа пользователями или же сопровождается объяснительным контентом. Сухой или эмоциональный аспект связан с тоном презентации данных, варьирующимся от серьезного до неформального, который может сделать презентации более эмоционально привлекательными с целью привлечения аудитории, менее разбирающейся в данных. Наконец, решающее значение имеет баланс между двусмысленностью и точностью, определяющий, насколько четко график передает свое сообщение по сравнению с любой намеренной двусмысленностью. Введенный Сибингой [27] каркас «когнитивной нагрузки» подразделяет когнитивные потребности на три типа. Внутренняя нагрузка связана со сложностью, присущей самим данным, с такими аспектами, как тип данных (количественные или качественные), определенность данных (определенные или неопределенные), ясность категорий данных (точные или неоднозначные) и соотнесенность данных с повседневной жизнью (конкретные или абстрактные). Уместная нагрузка зависит от готовности аудитории обрабатывать информацию, включая первоначальное отношение людей к визуализации (намеренное или случайное), время, которое у них есть на ее просмотр (медленное или быстрое), их знакомство с предметом (эксперт или новичок) и их удобство при работе с форматом данных (уверенность или тревожность). Наконец, посторонняя нагрузка касается способа презентации новой информации с учетом таких аспектов, как общность типа графика (распространенная или редкая), точность значений графика (точная или приблизительная), плотность информации (сжатость или подробность), а также является ли презентация данных в отчете самоочевидной или требует проведения обследования (объяснительная или разведывательная). Описанные выше каркасы дополняют друг друга в широкой области визуализации данных. Хотя принципы соотношения объема данных и объема информации и являются хорошим началом, сочетание этих каркасов улучшит ваш подход, учитывая различные потребности и аудитории. Ключ к эффективной интеграции этих каркасов заключается в понимании контекста, аудитории, сообщения и среды визуализации. Не следует бояться экспериментировать и тратить время на анализ чужих работ, чтобы развить свой вкус и накопить опыт. Примечание 19.2. Наконец, самый проверенный и верный метод тестирования графиков – попросить других взглянуть на них!
Краткий итог  199 19.3. Краткий итог Эта глава, посвященная основам визуализации данных, провела вас по основам визуального восприятия при презентации данных, подчеркнув важность предвнимательной и серийной обработки для понимания визуализаций. В данной главе были обследованы способы эффективного использования визуальных атрибутов, такие как цвет, форма и размер, с целью выделения ключевой информации, и рассмотрено взаимодействие интегрального и отделяемого восприятия в конструктивном исполнении визуализации. Подчеркнув роль когнитивной нагрузки, были рассмотрены вопросы того, как адаптировать визуализацию к контексту и потребностям аудитории. В следующей главе на основе этого фундаментального понимания будут обследованы способы создания графиков.
Глава 20 Визуализация данных Визуализация данных, несомненно, является самым захватывающим аспектом анализа – все любят красочные графики! Это также важнейший инструмент передачи сложной информации. В настоящей главе будет охвачено два варианта использования визуализации данных, будет обследована грамматика графики и введены методы создания интерактивных графиков. Давайте начнем с обследования двух главных типов визуализации. 20.1. Разведывательный и объяснительный типы В начале работы с новым набором данных вы, по сути, занимаетесь тем, что узнаете о нем и о взаимосвязях между многочисленными переменными внут­ри него. Этот подход называется разведывательным анализом данных, при котором проверяются допущения о данных и ищутся потенциально интересные связи, закономерности и аномалии. Хотя обычно принято полагаться на сводные статистики, такие как среднее значение и стандартное отклонение, эти числа могут заслонять отдельные точки данных, маскируя истинную форму наборов данных. Поэтому непосредственное наблюдение за фактическими данными не заменить ничем. Например, Матейка и Фитцморис [24] создали наборы данных с идентичными статистиками, которые выглядят совершенно по-разному. Выявленные ими разнообразные шаблоны доступны посредством пакета datasauRus. После того как результаты были скомпонованы, встает задача, как их презентовать аудитории, не имеющей отношения к технике. Такую аудиторию не будут волновать технические аспекты, к примеру использовалась ли в модели перекрестная валидация или как оптимизировался градиентно-усиленный лес. Они будут ожидать четкого и убедительного сообщения. Вот
Разведывательный и объяснительный типы  201 почему в презентациях, ориентированных на клиента, не найти причудливых, перегруженных графиков; дело всецело касается эффективной подачи сообщения. Давайте рассмотрим простой график, который вымышленная технологическая компания использовала для демонстрации превосходства своих процессоров P100. Они сосредоточились на том, чтобы донести ключевую мысль доступным и убедительным способом. Лично я, возможно, не знаю точной степени усовершенствования чипа P100, но я полностью убежден, что он действительно стал лучше. В разброс Динозавр Звезда Рис. 20.1  Грязная дюжина из пакета datasauRus Производительность чипа (чем выше, тем лучше) Чип Р100 другие чипы 13W Энергопотребление (чем ниже, тем лучше) Рис. 20.2  Объясняющий пример R предлагает массу пакетов для создания визуально привлекательных и информативных графиков. Одним из самых популярных и универсальных пакетов для визуализации данных на языке R является ggplot2. Далее мы пройдемся по основам использования пакета ggplot2 для создания графиков разных типов и их индивидуальной настройки в соответствии с вашими потребностями. Его можно загрузить отдельно, командой libary(ggplot2) либо командой libary(tidyverse).
202  Визуализация данных 20.2. Грамматика графики Пакет ggplot2 на языке R основан на принципах грамматики графики, то есть каркаса, разработанного Лиландом Уилкинсоном в его книге 1999 года «Грамматика графики» [38]. Эта система очерчивает правила визуальной презентации данных с помощью комбинации графических элементов и соотнесений между переменными данных и визуальными свойствами. Хэдли Уикхем позже адаптировал эти концепции для языка R [35]. Пользователи Excel, возможно, привыкли к простому рабочему процессу построения графиков: выбираешь тип графика, и он генерирует график за тебя. Рис. 20.3  Интерфейс построения графиков в Excel количество количество В традиционных системах построения графиков диаграммы рассеяния и столбчатые графики выглядят совершенно по-разному: Рис. 20.4  Диаграмма рассеяния и столбчатый график Однако, с точки зрения грамматики графики, между этими графиками есть поразительное сходство. Они отличаются только своей геометрией – в первом случае для презентации данных используются точки, а во втором – столбцы! Функция ggplot() пакета ggplot2 формирует базовую структуру графика. Дополнительные слои, такие как точки, линии и грани, добавляются с по-
Грамматика графики  203 мощью оператора +. Такой многослойный подход упрощает понимание, модификацию и построение сложных многослойных графиков. Приобретение навыков работы с пакетом ggplot2 имеет неоценимое значение, так как это не только дает возможность создавать визуализации, но и улучшает понимание процесса построения графиков. Например, давайте усовершенствуем приведенную выше гистограмму. Процент от общего Распределение правильных ответов в сдельной игре Количество правильных ответов Рис. 20.5  Улучшенная гистограмма В этой улучшенной версии теперь есть надписи, минимизированные линии решетки и всплеск цвета. Для тех, кто хочет глубже разобраться в пакете ggplot2, настоятельно рекомендуются такие ресурсы, как ggplot2: элегантная графика для анализа данных1 и Шпаргалка по пакету ggplot22. Далее давайте разложим процесс построения графика на этапы грамматики графики, демонстрируя, как создавать визуализацию послойно. 1. Данные: это базовый слой, на котором конкретизируется визуализируемый набор данных. Например, мы будем использовать набор данных iris, то есть встроенную серию обмеров цветков ириса (вид «Ирис щетинистый», или Iris setosa). #> #> #> #> #> #> #> 1 2 1 2 3 4 5 6 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 5.1 3.5 1.4 0.2 {I. setosa} 4.9 3.0 1.4 0.2 {I. setosa} 4.7 3.2 1.3 0.2 {I. setosa} 4.6 3.1 1.5 0.2 {I. setosa} 5.0 3.6 1.4 0.2 {I. setosa} 5.4 3.9 1.7 0.4 {I. setosa} См. https://ggplot2-book.org. См. https://posit.co/wp-content/uploads/2022/10/data-visualization-1.pdf.
204  Визуализация данных На уровне данных, по сути, имеется чистый холст, поскольку графические элементы еще не определены. data_layer <- ggplot(data = iris) data_layer Рис. 20.6  Слой данных 2. Эстетика: этот слой предусматривает определение визуальных свойств, которые представляют данные, таких как x, y, цвет или размер. При добавлении эстетики настраивается область построения графика. Например, отображение Sepal.Length (длины чашелистика) в x и Sepal. Width (ширины чашелистика) в y: aes_layer <- ggplot( data = iris, aes(x = Sepal.Length, y = Sepal.Width) ) aes_layer aes_layer mapping Рис. 20.7  Слой эстетики
Грамматика графики  205 #> #> #> Aesthetic mapping: * `x` -> `Sepal.Length` * `y` -> `Sepal.Width` 3. Геометрия: здесь определяется тип визуальных элементов, используемых для вывода данных на экран, таких как точки или столбцы. Добавление геометрии придает данным визуальную жизнь. Функции семейства geom_*(), такие как geom_point() для диаграмм рассеяния, geom_line() для линейных графиков и geom_bar() для столбчатых графиков, используются для конкретизации этих визуальных элементов на графике. geometry_layer <- aes_layer + geom_point() geometry_layer Рис. 20.8  Слой геометрии 4. Ш  калы: этот слой задает способ трансляции значений данных в визуальные свойства. Для таких аспектов, как цвет, размер или log(x), существуют разные шкалы. Добавление шкалы может менять внешний вид в зависимости от атрибутов данных. Например, эти свойства настраиваются функциями семейства scale_*(), такими как scale_color_ manual() для конкретно-прикладных цветов или scale_size_continuous() для размера. scales_layer <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) + geom_point() + scale_color_manual(values = c("red", "orange", "pink")) scales_layer scales_layer mapping #> Aesthetic mapping:
206  Визуализация данных #> * x -> Sepal.Length #> * y -> Sepal.Width #> * color -> Species Рис. 20.9  Слой шкал 5. Статистика: перед визуализацией данные могут быть подвергнуты математическим преобразованиям, таким как вычисление сводных статистик. Эти преобразования выполняются функциями семейства stat_*(), например функция stat_summary() используется для резюмирования данных. Некоторые функции семейства geom_*(), такие как geom_histogram(), внутренне используют статистические преобразования, подразделяя данные на корзины и подсчитывая наблюдения. stat_layer <- ggplot(data = iris, aes(x = Sepal.Length)) + geom_histogram(bins = 20, color = "white") stat_layer Рис. 20.10  Слой статистики
Грамматика графики  207 6. Фасеты: они предусматривают разбиение данных на подгруппы для отдельной визуализации. Фасеты (или грани, аспекты) могут обеспечивать более четкое сравнение между разными категориями. Для создания этих вспомогательных графиков используются функции семейства facet_*(), такие как facet_wrap() для упаковки панелей в решетку или facet_grid() для создания матрицы панелей. facets_layer <- geometry_layer + facet_wrap(vars(Species), ncol = 3) facets_layer Рис. 20.11  Слой фасет 7. Тема: это последние штрихи, которые помогают адаптировать внешний вид графика, включая шрифты, цвета и линии решетки, а также улучшают эстетику и удобочитаемость. Графики настраиваются индивидуально с помощью функции theme() или же применяются готовые темы, такие как theme_minimal() для лаконичного оформления или theme_bw() для классического стиля. theme_layer <- facets_layer + # Применить минимальную тему с базовым размером шрифта, равным 18 theme_minimal(base_size = 18) + # Добавить точки с размером 2 и коралловым цветом geom_point(size = 2, color = "#ffb86c") + # Индивидуально настроить параметры темы theme( # Сделать цвет фона графика темно-серым и цвет границы – серым plot.background = element_rect(fill = "#282a36", color = "#44475A"), # Удалить вспомогательные линии решетки panel.grid.minor = element_blank(), # Сделать цвет главных линий решетки серым panel.grid.major = element_line(colour = "#44475a"), # Сделать текст и цвет осей, а также # цвет текста полоски фасета белым axis.text = element_text(color = "#f8f8f2"),
208  Визуализация данных axis.title = element_text(color = "#f8f8f2"), strip.text = element_text(color = "#f8f8f2") ) + # Добавить надписи для осей x и y labs(x = "Sepal Length",y= "Sepal Width") + # Задать границы оси x в интервале от 4 до 8 xlim(4, 8) theme_layer Рис. 20.12  Слой темы 20.2.1. Графические интерфейсы для пакета ggplot2 Если это покажется немного сложным, то вовсе не обязательно начинать с нуля. Для построения графиков можно воспользоваться мощным пакетом esquisse с простым интерфейсом перетаскивания. Этот инструмент позволяет выбирать данные, геометрию и вносить практически любые необходимые изменения. В итоге получится готовый к работе полностью индивидуализированный график! Доступ к пакету esquisse можно получить, перейдя в Addins (Добавления) на верхней панели либо с помощью команды esquisser(your_data). # install.packages('esquisse') library(esquisse) esquisser(iris) А если нужны дополнительные способности по тематизации, то стилизовать график можно с помощью графического интерфейса пакета ggThemeAssist! Доступ к пакету ggThemeAssist можно получить, выбрав объект-график ggplot2, перейдя в Addins (Добавления) и кликнув на ggplot Theme Assistant (Помощник по темам ggplot). # install.packages("ggThemeAssist") library(ggThemeAssist)
Грамматика графики  209 Рис. 20.13  Пользовательский интерфейс пакета esquisse Рис. 20.14  Пользовательский интерфейс пакета ggThemeAssist
210  Визуализация данных 20.3. Интерактивные графики Хотя пакет ggplot2 отлично подходит для создания статических визуализаций, он не предлагает большого разнообразия в плане интерактивности по умолчанию, что могло бы пригодиться для более плотных графиков. Однако настоятельно рекомендуется овладеть искусством статической визуализации и не полагаться исключительно на интерактивность при передаче вашего сообщения. Если требуется добавить минимум интерактивности, то можно ознакомиться с пакетом ggiraph. В нем есть ряд функций, подобных функциям из пакета ggplot2, которые добавляют дополнительный уровень интерактивности, такую как всплывающие подсказки, выбор из нескольких опций и многое другое. Самым простым способом добавления интерактивности является функция ggplotly в пакете plotly. Она предлагает простой метод конвертации рисунков ggplot2 в интерактивные визуализации plotly. Указанная функция особенно удобна в ситуациях, когда вы имеете дело с большим количеством точек данных, которые было бы трудно различить на статическом графике. library(plotly) p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) + geom_point(size = 1, alpha = 1) + theme_minimal() # Конвертировать график ggplot2 в график plotly pp <- ggplotly(p) pp Рис. 20.15  Пример с использованием пакета ggplotly
Интерактивные графики  211 20.3.1. HTML-виджеты Для тех, кто ищет продвинутую веб-интерактивность на языке R, существует проект htmlwidgets, который обязателен к ознакомлению. Он легко интегрирует язык R с мощными библиотеками JavaScript, позволяя использовать такие выдающиеся инструменты визуализации, как plotly, leaflet и DT (таб­ лицы данных). Пакет ggplotly() позволяет конвертировать рисунки пакета ggplot2 в интерактивные графики, но пакет plotly также позволяет создавать эти визуа­ лизации с нуля. Однако прямое создание визуализаций посредством пакета plotly обеспечивает повышенную гибкость и доступ к функциональным средствам, которые могут быть недоступны посредством выполняемой пакетом ggplot2 конверсии. library(plotly) # Диаграмма рассеяния: # Длина чашелистиков в сопоставлении с их шириной, раскраска по видам p <- plot_ly( data = iris, x = ~Sepal.Length, y = ~Sepal.Width, color = ~Species, type = "scatter", mode = "markers", marker = list(size = 6), hovertemplate = 'Sepal Length: %{x}<br>Sepal Width: %{y}<br><extra></extra>' ) # Индивидуально настроить макет графика p <- layout( p, title = "Sepal Measurements", xaxis = list(title = "Sepal Length"), yaxis = list(title = "Sepal Width") ) p
212  Визуализация данных Рис. 20.16  Пример с использованием пакета plotly Пакет echarts4r в R служит оболочкой для универсальной библиотеки Java­ Script ECharts. Он поддерживает большое количество типов графиков, таких как столбчатые, линейные, точечные (диаграммы рассеяния), круговые и радарные. Вся мощь библиотеки ECharts особенно сильно проявляется при создании сложных, многорядовых, интерактивных графиков, при этом он поддерживает широкий спектр возможностей индивидуальной настройки. Пакет предлагает впечатляющую анимацию и интерактивность, что делает его отличной альтернативой пакету plotly. library(echarts4r) e_chart <- iris %>% group_by(Species) %>% # Сгруппировать по виду # Инициализировать график длиной чашелистика на оси x e_charts(Sepal.Length) %>% # Добавить диаграмму рассеяния с шириной чашелистика на оси y e_scatter(Sepal.Width, symbol_size = 7) %>% e_y_axis(min = 1.5, max = 5) %>% # Задать диапазон оси y e_x_axis(min = 4, max = 8) %>% # Задать диапазон оси x e_axis_labels(x = "Sepal Width",y= "Sepal Length") %>% # Пометить оси e_tooltip( trigger = "item", formatter = htmlwidgets::JS(" function(params){ return('Sepal Length: ' + params.value[0] + '<br />Sepal Width: ' + params.value[1])
Краткий итог  213 } ") ) # Добавить всплывающую подсказку e_chart Рис. 20.17  Примеры с использованием библиотеки Echarts 20.4. Краткий итог В этой главе было представлено подробное руководство по визуализации данных на языке R, подчеркивающее важность как разведывательного, так и объяснительного подходов. Были обследованы универсальность пакета ggplot2, основанного на грамматике графики, и рассмотрены способы привнесения интерактивности в визуализацию. В следующей главе будут представлены различные типы графиков и примеры их практического применения.
Глава 21 Подходящий график для работы При работе с графиками не спрашивайте себя, какой график использовать. Вместо этого спрашивайте: что я пытаюсь показать? В этом разделе будут рассмотрены различные типы графиков, их предназначение и ситуации, когда их следует использовать. Хоть мы и не будем рассматривать все возможные графики, вы, несомненно, расширите свой инструментарий. 21.1. Сравнение категорий Графики для сравнения категорий – это тип визуализации данных, который используется для сравнения и противопоставления разных категорий или групп. Наиболее распространенным из них является столбчатый график. На приведенном ниже графике показаны пять стран-лидеров по ВВП на душу населения в 1997 году. Очевидно, что Норвегия занимает первое место, а Швейцария – пятое. Топ-5 стран по ВВП на душу населения в 1997 г. 41 283 Норвегия 40 301 Кувейт 35 767 33 519 32 135 США Сингапур Швейцария Рис. 21.1  Столбчатый график
Сравнение категорий  215 Вертикальные столбчатые графики отлично подходят для быстрого сравнения небольшого числа категорий (менее семи). Однако если нужно показать ранжирование большего количества элементов, то можно попробовать перевернуть ось столбчатого графика. Горизонтальные столбчатые графики обладают дополнительным преимуществом, которое заключается в том, что они отлично подходят для показа длинных имен. Ниже приведены результаты выборов в Лондоне в 2021 году, на которых британский ютубер Нико Омилана занял пятое место. Другой ютубер, Макс Фош, тоже преодолел минимальный порог. Результаты выборов мэра Лондона (2021) по % голосов Рис. 21.2  Вертикальный столбчатый график 21.1.1. Леденцовый график Леденцовый график (lollipop chart, также график «леденец на палочке») является одним из самых популярных, в особенности по сравнению с обычными столбчатыми графиками (рис. 21.3). Его уникальная особенность состоит в том, что он позволяет наглядно иллюстрировать положение точки данных в двумерном пространстве. Как показывает практика, полезность леденцового графика по сравнению со столбчатым заключается в учете невозможности наращивать данные. Например, поскольку проценты нельзя наращивать, более подходящим является леденцовый график. 21.1.2. Пулевой график Менее распространенным визуальным конструктом является пулевой график (bullet graph, также график-шкала). Это мощный инструмент, предназначенный для сравнения производительности с заранее определенной це-
216  Подходящий график для работы левой зоной-мишенью. Давайте его протестируем, визуализировав чистый коэффициент потребительской лояльности (Net Promoter Score, аббр. NPS). На графике четко показана мишень, различные уровни результативности и то, как результаты соотносятся с поставленной целью. Выборы мэра Лондона (2021) по % голосов Рис. 21.3  Леденцовый график Чистый коэффициент потребительской лояльности за 2023 г. Мы перевыполнили план! Плохо Хорошо Отлично Мишень Рис. 21.4  Пулевой график 21.2. Распределение Что делать, если требуется показать распределение данных? Для этого можно применить вариант столбчатого графика – гистограмму (histogram). Гистограммы показывают распределение непрерывных данных, группируя данные в корзины и показывая частоту или долю наблюдений в каждой корзине.
Распределение  217 Они отлично подходят для визуализации формы распределения, но очень чувствительны к выбору корзин. Давайте воспользуемся набором данных iris, чтобы продемонстрировать, как количество корзин влияет на график длины чашелистиков. Обратите внимание, как форма распределения меняется в зависимости от количества корзин. Важно соблюдать баланс между слишком малым и слишком большим количеством корзин. Благодаря шести корзинам распределение выглядит довольно нормальным, а вот из-за тридцати корзин оно смотрится уже хаотичным. Пятнадцать корзин выглядят примерно правильно, сохраняя бимодальный характер распределения и поддерживая при этом четкость изображения. Гистограммы с распределением длин чашелистиков ириса с варьирующимися корзинами 6 корзин 15 корзин 30 корзин Рис. 21.5  Гистограммы 21.2.1. График плотности В отличие от гистограмм, на графиках плотности (density plots) данные показываются не столбиками, а непрерывной линией. Эта плавная кривая обеспечивает более детальное и нюансированное представление распределения, облегчая выявлять закономерности и тренды. Графики плотности строят эту линию, помещая множество малых нормальных распределений в каждую точку данных, которые затем используются для взвешивания всех точек внутри соответствующих диапазонов и построения соединяющей их кривой. Ширина указанных кривых определяется шириной полосы пропус­ кания у графика плотности, определяющего ширину охвата кривых. При большей полосе пропускания будет учитываться большее количество точек, что приводит к более плавной кривой, а при меньшей полосе пропускания линия получится ломаной.
218  Подходящий график для работы Графики плотности с распределением длин чашелистиков ириса с варьирующимися ширинами полос Ширина полосы 0,3 Ширина полосы 0,1 Ширина полосы 0,03 Рис. 21.6  Графики плотности 21.2.2. Многоугольник частот Многоугольник частот (frequency polygon) похож на гистограмму, но вместо столбцов в нем используется непрерывная линия, которая соединяет точки, представляющие частоты. Многоугольники частот особенно полезны при сравнении двух или более наборов данных на одном графике. Как и гистограммы, они основаны на выборе корзин. 15 корзин 15 корзин Виды Рис. 21.7  Многоугольник частот
Распределение  219 21.2.3. Коробчатый график Коробчатый график (box plot, также график «ящик с усами») дает сводную информацию о распределении набора данных, показывая медиану, нижний и верхний квартили, а также минимальное и максимальное значения. Прямоугольник посередине представляет межквартильный диапазон (interquartile range, аббр. IQR), то есть диапазон средних 50 % данных. Горизонтальная линия внутри прямоугольника представляет медиану, точку данных ровно посередине в наборе данных. Усы вверху и внизу расширяются до минимального и максимального значений, исключая выбросы. Просто невероятно, сколько информации содержится в коробчатых графиках! Используя всего один график, можно быстро выявить выбросы и получить наглядное представление о распределении данных. В контексте набора данных iris коробчатый график длины чашелистиков у разных видов цветков дает четкое представление о распределении этой переменной. Обратите внимание, насколько существенно различаются статистические данные у разных видов цветков. Однако, как и в случае с реальными коробками, коробчатые графики также могут скрывать важную информацию. В качестве иллюстрации этого момента можно использовать наборы данных с одинаковыми сводными статистиками, но разными распределениями. На втором графике показаны три идентичных коробчатых графика. Однако стоит добавить точки данных в график, станет очевидно, что распределения сильно отличаются. Группа 1 Группа 2 Группа 3 Группа 1 Группа 2 Группа 3 Рис. 21.8  Коробчатые графики 21.2.4. Скрипичный график Одним из решений является использование скрипичного графика (violin plot), который, по сути, представляет собой вертикальный график плотности. Посмотрите, насколько больше можно узнать о распределении данных по
220  Подходящий график для работы видам ириса. Хорошо видны распределение плотности, точки и квантили. Как вы помните, при построении графиков плотности очень важна величина полосы пропускания. Настройка надлежащей полосы пропускания показывает истинное распределение. Рис. 21.9  Скрипичный график 21.2.5. Ульевый график Ульевый график (bee hive plot, график «пчелиный улей», или «пчелиный рой») представляет собой диаграмму рассеяния, на которой точки данных расположены таким образом, чтобы минимизировать их наложение. Он идеально подходит для визуализации малых наборов данных, так как создает закономерности или узоры, подобные графику плотности, не скрывая отдельные точки данных. Группа 1 Группа 2 Рис. 21.10  Ульевый график Группа 3
Распределение  221 Все рассмотренные выше графики имеют свои преимущества: 1. Коробчатый график показывает важные статистические показатели. 2. График плотности обеспечивает высокоуровневое представление формы данных. 3. Ульевый график «показывает» фактические точки данных. Хотя сочетание этих графиков может придавать перенасыщенность визуальному ряду, при внесении некоторых изменений все же можно создать гиб­ ридный график, который будет отражать сильные стороны каждого из них. 21.2.6. График дождевых облаков График дождевых облаков (rain cloud plot) сочетает в себе элементы коробчатого, скрипичного и ульевого графиков, создавая образ облаков, из которых «идет дождь». В нем задействуется график плотности, чтобы показывать распределение данных, коробчатый график, чтобы показывать статистики и отдельные точки данных, представленные в виде капель дождя, в результате чего получается внешне привлекательный и информативный способ визуализации большого количества распределений рядом друг с другом, позволяющий легко сравнивать и выявлять закономерности. Разве он не прекрасен? Тут есть коробчатый график, график плотности и дрожащие точки − и все это на одном графике, который не выглядит загроможденным. Более того, можно четко видеть, как различаются распределения синтетических наборов данных. Группа 1 Группа 2 Группа 3 Рис. 21.11  Графики дождевых облаков Лично мне больше всего нравится горизонтальный вариант с вертикальными черточками вместо точек, графиком плотности и графиком пластов (slab plot) вместо коробчатого графика. На графике пластов толстая линия обозначает межквартильный размах (IQR), точка посередине обозначает ме-
222  Подходящий график для работы диану, а более светлые линии служат в качестве усов. Хотя этот вариант может быть привлекательным с визуальной точки зрения, важно убедиться, что ваша аудитория понимает эту визуализацию. Возможно, потребуется предоставить дополнительный контекст или включить примечание, объясняющее значение линий и штрихов, чтобы избежать путаницы. Группа 3 Группа 2 Группа 1 Рис. 21.12  Горизонтальные графики дождевых облаков 21.2.7. Графики по краям Графики по краям (marginal plots) – это метод визуализации распределения данных относительно двух переменных. В этой визуализации для каждой переменной по краям графика рассеяния расположен график плотности. За счет этого появляется возможность обследовать как индивидуальное распределение каждой переменной, так и взаимосвязь между ними. Обратите внимание, как ширина и длина чашелистиков образуют четкие группировки и демонстрируют уникальное распределение для каждого вида ирисов. Рис. 21.13  Графики по краям
Пропорции  223 21.3. Пропорции Еще одна большая коллекция графиков посвящена передаче пропорций и композиции. 21.3.1. Многослойный столбчатый график Многослойный столбчатый график (stacked bar chart) – это тип графика, который используется для визуализации распределения категориальной переменной. Он похож на обычный столбчатый график, но в многослойном столбчатом графике каждый столбец подразделен на секции, каждая из которых представляет отдельную категорию внутри переменной. Высота каждой секции соответствует доле или частоте использования категории в пределах этого столбика. Многослойные столбчатые графики особенно полезны при сравнении распределения переменной с разными подгруппами или периодами времени, поскольку они позволяют легко визуализировать как совокупное распределение, так и относительные пропорции каждой подгруппы или категории внутри переменной. В качестве примера давайте возьмем данные о расходах в США по департаментам. Показаны только четыре крупнейших департамента, остальные собраны в разделе «Other» (Прочие). На приведенном ниже графике видим абсолютные значения и их составляющие по годам. Обратите внимание на то, как общая сумма расходов увеличивается с каждым годом, а также на изменения в структуре. Сможете ли вы сказать, какие департаменты внесли наибольший вклад в этот рост? Расходы США по департаментам в млрд долларов по годам Рис. 21.14  Многослойный столбчатый график
224  Подходящий график для работы Что, если интересуют не абсолютные значения, а относительные пропорции? Для этого можно использовать многослойный график с разбивкой по процентам (percentage-stacked chart). Многослойные графики широко применяются для визуализации распределения категориальных переменных, но с ними бывает сложно сравнивать категории в середине. Как правило, проще всего сравнивать категории, расположенные вверху и внизу стопки. Например, предположим, что нужно сравнить тренды в Министерстве обороны (Defense) и Управлении социального обеспечения (SSA) во временной динамике. В этом случае указанные категории можно переместить в верхнюю и нижнюю части многослойного графика, чтобы упростить сравнение их относительных размеров и трендов. Пропорции расходов США по департаментам Рис. 21.15  Многослойный столбчатый график с разбивкой по процентам 21.3.2. Круговой график Круговые графики (pie charts, также диаграмма-торт) – это, по сути, столбчатые графики, преобразованные в полярную систему координат, каждая категория в которых представлена в виде среза круга, или ломтика. Хотя круговые графики могут эффективно передавать информацию в ситуациях, когда одна категория значительно больше или меньше других, их становится трудно читать и сравнивать в ситуациях, когда категорий много или когда различия между ними невелики. Сравнение углов и площадей срезов может приводить к путанице и неправильному толкованию данных. В качестве примера давайте возьмем экспортную корзину Японии за 2020 год1. Можете ли 1 Данные взяты из: Лаборатория экономического роста Гарвардского университета, Атлас экономической сложности. http://www.atlas.cid.harvard.edu.
Пропорции  225 вы определить максимальные и минимальные объемы японского экспорта? Как насчет третьего по величине? сектор Рис. 21.16  Круговой график Но если абсолютно необходимо использовать круговой график, то вот несколько правил, о которых следует помнить: 1. Ограничивать количество категорий максимум пятью−семью. 2. Рассмотреть возможность группировки небольших категорий в категорию «Прочее» во избежание беспорядка. 3. Располагать ломтики в порядке убывания размера, начиная с 12 часов, чтобы их было легче сравнивать. 4. Указывать имена категорий непосредственно на графике, вместо того чтобы полагаться исключительно на легенду. 5. Добавлять разделители между фрагментами, которые будут помогать их различать. Однако надо иметь в виду, что данный тип графиков также может создавать визуальный беспорядок, поэтому их следует использовать осмотрительно. Рис. 21.17  Улучшенный круговой график
226  Подходящий график для работы 21.3.3. Вафельный график Альтернативой круговому графику может быть вафельный график (waffle chart, только от одного названия появляется чувство голода). Это визуализация в виде решетки, которая напоминает вафлю или шахматную доску. Каждый квадрат в решетке представляет определенную долю от общего объема данных, что делает его удобным способом визуализации пропорций или процентов в визуально привлекательном виде. Однако такие графики тоже уязвимы в случае большого количества категорий. Но в чем они действительно хороши, так это в том, что дают представление о пропорциях и размерах. Вафельные графики значительно выигрывают от интерактивности. Рис. 21.18  Вафельный график 21.3.4. Древовидные карты Что делать, если имеется много иерархических данных? Для этого существуют древовидные карты! Древовидные карты (treemaps) – это тип визуализации, который позволяет выводить на экран иерархические данные простым для понимания способом. Каждый узел в иерархии представлен прямо­ угольником, размер которого соответствует доле в общем объеме данных. Узлы организованы таким образом, чтобы сохранять иерархию, при этом родительские узлы содержат дочерние узлы меньшего размера. Благодаря этому можно быстро выявлять, какие узлы являются самыми большими, а какие – самыми маленькими, а также взаимосвязи между ними. Древовидные карты особенно полезны для показа больших объемов данных в компактной и интуитивно понятной форме. Древовидные карты бывают очень громоздкими, и для таких подробных графиков почти всегда необходима интерак-
Корреляция  227 тивность. Ознакомьтесь с тем же графиком на источниковом веб-сайте по адресу https://atlas.cid.harvard.edu/countries/114/export-basket. Экспорт из Японии за 2020 г. Рис. 21.19  Древовидная карта 21.4. Корреляция Помимо понимания распределения отдельных переменных, важно обследовать взаимоотношение между парами переменных. Корреляционные графики являются полезным инструментом визуализации многочисленных аспектов данных: например, взаимоотношений между переменными (или их отсутствия), кластеризации и выбросов. 21.4.1. Диаграмма рассеяния Наиболее распространенной визуализацией является диаграмма рассеяния (scatter plot), рис. 21.20. Не секрет, что диаграммы рассеяния представляют собой удивительные и, возможно, наиболее убедительные виды графиков. В данный график можно добавлять подогнанные линии, чтобы лучше показывать взаимоотношения между переменными. Возвращаясь к цветкам ириса, обратите внимание на отличный угол наклона линии для Iris setosa (Ирис щетинистый) по сравнению с двумя другими видами. Что это говорит о закономерностях развития данного вида? 21.4.2. Коррелограммы Коррелограммы (correlograms) служат эффективным инструментом для оперативной визуализации взаимосвязей в наборе данных. Они позволяют ви-
228  Подходящий график для работы зуализировать корреляции между всеми парами переменных, что особенно удобно при обследовании многопеременных наборов данных. Есть несколько способов структурирования коррелограмм, но наиболее распространенный из них представлен на рис. 21.23. Хотя на первый взгляд он может показаться беспорядочным, он помогает быстро выявлять любые взаимосвязи, существующие в данных. Рассматривая рисунок, подумайте о том, какие характеристики могут быть полезны для различения этих трех видов. Рис. 21.20  Диаграмма рассеяния Рис. 21.21  График коррелограмм
Изменение во временной динамике  229 21.5. Изменение во временной динамике Выше уже было представлено несколько графиков, которые отражают изменение во времени. На графиках временных рядов обычно по оси x откладывается время, а по оси y – измеряемая переменная. Они могут отображать тренды, закономерности и сезонные колебания в данных. 21.5.1. Линейный график Линейные графики (line charts), пожалуй, наиболее интуитивно понятны. Для меня они тесно связаны с финансами. Поэтому давайте взглянем на индекс фондового рынка S&P 500, который составляется с 1927 года. Исторические данные скорректированы с учетом инфляции, используя основной индекс потребительских цен, и каждая точка данных представляет собой итоговое значение на конец месяца. По сравнению с графиками рассеяния, на них значительно проще увидеть общую картину с первого взгляда. Рис. 21.22  Линейный график 21.5.2. Водопадный график Водопадные графики (waterfall charts), также именуемые мостовыми диаграммами, представляют собой разновидность столбчатых графиков и используются для визуализации кумулятивного эффекта от последовательно вводимых положительных или отрицательных значений. График называется «водопадным», потому что он напоминает последовательность падаю-
230  Подходящий график для работы Деньги в банке щих капель воды. Каждый столбик на графике представляет собой значение и обозначен цветом, указывающим на то, способствует ли он увеличению либо уменьшению кумулятивной суммы. Они полезны для визуализации относительного вклада положительных и отрицательных факторов, которые влияют на чистое изменение анализируемого значения. Например, водопадный график можно использовать для того, чтобы показать, как менялся баланс банка на протяжении многих лет. Рис. 21.23  Водопадный график 21.6. Краткий итог В этой главе все внимание было уделено выбору подходящих графиков для конкретных задач. Как вы, должно быть, заметили, существует огромное количество задач и столь же разнообразных графиков на выбор. Выбор правильного инструмента визуализации имеет решающее значение для успеха презентации. Вооружившись этим расширенным набором, давайте перейдем к следующей главе, которая научит вас использовать цвета для усиления визуализаций.
Глава 22 Цветовые данные Если речь идет о визуализации данных, то решающее значение имеет эффективное использование цвета. Цвет может привлекать внимание к ключевым элементам данных, повышать визуальную привлекательность и облегчать понимание сложной информации. Продуманная цветовая гамма привлекает внимание зрителя, выделяет важные детали и помогает дифференцировать категории в данных, делая общее сообщение более четким и запоминающимся. Цвета не просто придают графикам привлекательный вид; они могут вызывать эмоции и передавать смыслы, которые было бы трудно выразить иначе. Например, в Соединенных Штатах красный часто символизирует опасность или страсть, синий – спокойствие или печаль, а зеленый – природу или здоровье. Но в разных культурах эти значения могут сильно различаться, поэтому при выборе цвета важно учитывать аудиторию. Влияние цвета настолько велико, что с 1979 года раздевалки на стадионе «Кинник» в Айове были выкрашены в розовый цвет, предположительно чтобы снизить уровень тестостерона у гостевых команд. Используя цвет стратегически, можно делать визуализацию данных более притягательной и эффективной, обеспечивая не только понимание аудиторией представленной информации, но и ее запоминание. 22.1. Какие цвета выбирать Цвет используется для выделения конкретных данных и предоставления контекста. Давайте рассмотрим два графика, на которых сравнивается валовой внутренний продукт (ВВП) европейских стран в 1997 году. На первом графике каждой стране назначен определенный цвет, что создает визуальную какофонию, напоминающую «взрыв на кондитерской фабрике». На втором графике результат улучшен за счет минимизации отвлекающих факторов. На нем выделена Греция, а остальные страны обозначены серым цветом. Использование «красного» для Греции служит сигналом, намекающим на то, что ее экономические показатели, возможно, не на должном уровне.
232  Цветовые данные Страны Европы по ВВП на душу населения Норвегия Швейцария Нидерланды Дания Австрия Исландия Германия Бельгия Великобритания Франция Швеция Италия Ирландия Финляндия Испания Греция Португалия Словения Чехия Словакия Венгрия Польша Хорватия Сербия Румыния Турция Черногория Болгария Босния Албания Норвегия Швейцария Нидерланды Дания Австрия Исландия Германия Бельгия Великобритания Франция Швеция Италия Ирландия Финляндия Испания Греция Португалия Словения Чехия Словакия Венгрия Польша Хорватия Сербия Румыния Турция Черногория Болгария Босния Албания ВВП на душу населения ВВП на душу населения Рис. 22.1  Выделение цветом 22.1.1. Взаимодополняющая гармония с положительной/отрицательной коннотацией Взаимодополняющая гармония предусматривает использование цветов, расположенных прямо напротив друг друга на цветовом колесе (например, на рис. 22.2), создавая резкий контраст. Этот метод эффективно передает положительную/отрицательную коннотацию и идеально подходит для подчеркивания различий. Цвета, расположенные рядом на колесе, друг друга дополняют, и в то же время цвета, расположенные напротив, обеспечивают наиболее существенное усиление ключевого цвета. На следующем ниже рисунке сравнивается рост населения в Азии и Европе. Здесь ярко-фиолетовый цвет подчеркивает значительный рост населения в Азии, а зеленый – сравнительно более медленный рост в Европе.
Какие цвета выбирать  233 Население в миллионах (log10) Рис. 22.2  Цветовое колесо Азия Европа Рис. 22.3  Взаимодополняющая гармония с положительной/отрицательной коннотацией 22.1.2. Почти взаимодополняющая гармония для выделения двух рядов, один из которых находится в центре внимания Почти взаимодополняющая гармония – это цветовая схема, которая обеспечивает существенный контраст, не прибегая к использованию диаметрально противоположных цветов на цветовом колесе. Вместо этого выбирается цвет, расположенный на расстоянии 33 % от первичного цвета, а не целых 50 % от него. Этот метод эффективен при выделении двух рядов, один из которых
234  Цветовые данные Население в миллионах (log10) находится в центре внимания. Для ключевых рядов предпочтительнее использовать теплые цвета, а для дополняющих – холодные. При необходимости интенсивность дополняющих цветов можно приглушать, уменьшая их насыщенность или изменяя яркость, тем самым снижая контраст с фоном. Приведенный ниже пример подчеркивает важность роста населения Азии, в то время как Европа представлена нейтрально, в качестве сравнительного примера, а не региона с медленным ростом. Азия Европа Рис. 22.4  Почти взаимодополняющая гармония для выделения двух рядов, один из которых находится в центре внимания 22.1.3. Аналогичная/триадическая гармония для выделения трех рядов Аналогичная гармония эффективна для проведения простых различий между категориями с помощью ключевого цвета и двух соседних цветов на цветовом колесе. Этот метод, хотя и прост, позволяет ключевому цвету выделиться немного больше. Он отлично подходит для показа не менее важных категорий, например для демонстрации роста населения, не акцентируя внимания на каких-либо его аспектах. Вы уже познакомились с триадической гармонией при сравнении двух категорий. Здесь триадическая гармония может эффективно применяться для сравнения трех континентов. Напомним, что, регулируя оттенок цветов, можно увеличивать или уменьшать акцент в зависимости от необходимости. Обратите внимание на разницу в восприятии между аналогичной и триадической гармониями – в чем она заключается?
Население в миллионах (log10) Какие цвета выбирать  235 Азия Америки Европа Население в миллионах (log10) Рис. 22.5  Аналогичная гармония для выделения трех рядов Азия Америки Европа Рис. 22.6  Триадическая гармония для выделения трех рядов 22.1.4. Выделение одного ряда на фоне двух соотнесенных рядов Цветовая схема на основе почти взаимодополняющей гармонии позволяет выделять один ряд на фоне других. На следующем ниже графике четко показан ВВП Азии, представленный ярким фиолетовым цветом. И наоборот, Европа и Америки, изображенные гармоничными зелеными цветами, играют в этом повествовании второстепенную роль.
ВВП на душу населения (log10) 236  Цветовые данные Европа Америки Азия Рис. 22.7  Выделение одного ряда на фоне двух соотнесенных рядов 22.1.5. Схема на основе аналогичной взаимодополняющей гармонии для одного главного ряда и трех вторичных ему рядов ВВП на душу населения (log10) Схема на основе аналогичной взаимодополняющей гармонии, предусматривающая четыре различающихся цвета, обеспечивает отличную платформу для выделения первичного ряда наряду с тремя соотнесенными компонентами. В этой схеме ключевой цвет выделяется благодаря сходству трех дополняющих цветов. Ее иллюстрацию можно увидеть в следующем ниже примере, демонстрирующем так называемое Малазийское экономическое чудо наряду с тремя соседними странами. Малайзия Таиланд Индонезия Вьетнам Рис. 22.8  Схема на основе аналогичной взаимодополняющей гармонии для одного главного ряда и трех его компонентов
Какие цвета выбирать  237 22.1.6. Схема на основе двойной взаимодополняющей гармонии для двух пар, одна из которых является доминирующей ВВП на душу населения (log10) Схема на основе двойной взаимодополняющей гармонии идеально подходит для визуализации четырех рядов данных, подразделенных на две отдельные пары. Она предусматривает ключевой цвет, смежный цвет и соответствующие им противоположности на цветовом колесе. Для ключевого и смежных цветов предлагаются более теплые цвета, а для их взаимодополняющих противоположностей – более холодные тона. Такое цветовое решение выгодно выделяет одну пару из другой. Как показано ниже, Швейцарии и Норвегии по ВВП за 1952 год составляют одну группу, показанную фиолетовыми оттенками, в то время как Босния и Албания, выделенные зелено-синими, образуют другую группу. Норвегия Швейцария другие Албания Босния Рис. 22.9  Схема на основе двойной взаимодополняющей гармонии для двух пар, среди которых одна пара доминирует 22.1.7. Прямоугольная или квадратная схема на основе взаимодополняющей гармонии для четырех рядов с одинаковым акцентом Прямоугольная или квадратная схема на основе взаимодополняющей гармонии подходит для визуализации данных четырех рядов с одинаковым акцентом. В отличие от схемы на основе двойной взаимодополняющей гармонии, она включает ключевой цвет, его дополнение и два дополнительных цвета для формирования прямоугольника или квадрата на цветовом колесе,
238  Цветовые данные ВВП на душу населения (log10) в результате чего для каждого из четырех рядов получаются различающиеся цвета. Несмотря на сходство со схемой на основе двойной взаимодополняющей гармонии, эта схема оптимальна в ситуациях, когда все ряды имеют одинаковую важность. Например, на следующем ниже графике показаны так называемые четыре азиатских тигра – Гонконг, Сингапур, Южная Корея и Тайвань. Все эти страны, быстро развивавшиеся с 1960-х по 1990-е годы, в равной степени важны для иллюстрации динамизма экономического роста Восточной Азии. Сингапур Гонконг Тайвань Южная Корея Рис. 22.10  Прямоугольная или квадратная схема на основе взаимодополняющей гармонии для четырех рядов с одинаковым акцентом 22.1.8. Схема последовательных цветов В схеме последовательных цветов задействуется градиент от светлого к темному, отображая числовые значения на основе оттенка или яркости/светлоты. В зависимости от фона при более низких значениях получаются более светлые цвета, а при более высоких – более темные оттенки. Можно использовать один оттенок или их последовательность. Давайте применим уже использовавшийся фиолетовый цвет для визуализации показателей смертности от COVID-19 на 100 000 населения в Соединенных Штатах1. Если серый цвет обозначает минимум, а ярко-фиолетовый – максимум, то можно ли определить штаты с наименьшим и наибольшим количеством смертей? Легко ли вам соотнести цвет с соответствующим значением? 1 Данные взяты из https://covid.cdc.gov/covid-data-tracker/#maps_deaths-rate-total.
Какие цвета выбирать  239 Уровень смертности от COVID-19 на 100 000 человек Рис. 22.11  Схема последовательных цветов 22.1.9. Схемы с расходящимися цветами Схемы с расходящимися цветами используются в ситуациях, когда числовая переменная имеет значимое центральное значение, например ноль (рис. 22.12). В этой схеме совмещаются две последовательные палитры с общим концом, центрированным на центральном значении. Положительные значения получают цвета с одной стороны спектра, а отрицательные – с другой. В идеале центральное значение должно иметь светлый оттенок, чтобы более темные цвета обозначали большее отклонение от центра. Простота здесь является ключевым моментом, чтобы не размывать вменяемый смысл и не вводить в заблуждение зрителей. Давайте прошкалируем числа так, чтобы в качестве значения они представляли стандартное отклонение. Обратите внимание, что штаты со значительно меньшим количеством смертей выделены синим цветом, а штаты со значительно большим количеством смертей – желтым, в то время как штаты с числами, близкими к среднему значению, выделены сероватым цветом. Легко ли вам определить состояния, близкие к среднему значению (без стандартных отклонений)? 22.1.10. Предварительно созданные шкалы Предварительно созданные цветовые шкалы, такие как Viridis, разработаны для обеспечения единообразности в восприятии, что придает визуальную привлекательность и простоту истолкования. Они предоставляют стандартную, единообразную цветовую схему, устраняя необходимость в создании и тестировании схем на заказ. Более того, они помогают людям с дальтонизмом истолковывать визуализацию данных благодаря взаимоувязанному
240  Цветовые данные визуальному контрасту. Задействуя предварительно созданные цветовые шкалы, визуализация данных становится доступной широкой аудитории. Как вы считаете, проще ли соотносить цвета со значениями и группировать состояния со схожими значениями с такими шкалами? Шкалированный уровень смертности от COVID-19 Единицы стандартного отклонения Рис. 22.12  Схема с расходящимися цветами Уровень смертности от COVID-19 на 100 000 человек Рис. 22.13  Предварительно созданная цветовая схема Viridis 22.2. Цветовые системы Люди воспринимают цвета иначе, чем машины. Например, цвета, которые кажутся машине похожими на красный, зеленый, синий (red, green, blue, аббр. RGB), могут не восприниматься человеческим глазом. Следующие ниже изображения иллюстрируют концепцию единообразия восприятия с исполь-
Цветовые системы  241 зованием двух цветовых шкал: одной RGB, которая неоднородна по восприятию, и другой HCL (hue, chroma, lightness, или оттенок, насыщенность/ хроматичность, яркость/светлота), которая более или менее однородна. При просмотре в оттенках серого становится очевидной неоднородность цветового колеса RGB. Обратите внимание на наличие светлых и темных участков и сравните это с версией HCL, которая является однородной. В техническом плане однородное цветовое пространство обеспечивает, что воспринимаемая человеческим глазом разница между двумя цветами будет пропорцио­ нальна евклидову расстоянию1 в пределах данного цветового пространства – другими словами, внешне похожие цвета имеют одинаковые значения параметров. RGB Цветовое колесо HCL Цветовое колесо Рис. 22.14  Однородное восприятие Что же касается выбора цвета, то нужен способ описывать его не только на английском языке. Для решения этой проблемы в цифровом дизайне и визуализации данных широко используются несколько популярных цветовых систем. Стандартным цветовым пространством для вывода изображений и графики на цифровых дисплеях является стандартная цветовая система RGB (sRGB), то есть зависящее от устройства цветовое пространство, предназначенное для обеспечения взаимоувязанной цветопередачи на широком спектре устройств. Система RGB отлично подходит для одной-единственной цели: сообщать пикселам на дисплее, что именно им нужно делать, и не более того. Значительным улучшением является цветовая система HSV. Данную систему можно трактовать как более удобную для пользователя трансформацию системы RGB, поскольку с ее помощью значительно проще находить 1 Евклидово расстояние – это расстояние по прямой между двумя точками в многомерном пространстве, вычисленное с использованием теоремы Пифагора.
242  Цветовые данные гармоничные цвета и изменять понятные человеку параметры: оттенок, насыщенность и значение. Оттенок, обозначаемый значением от 0 до 360 градусов на цветовом колесе, определяет основополагающий цвет пиксела. Насыщенность означает чистоту оттенка, представляющую степень смешивания серого с цветом в диапазоне от 0 % (серый) до 100 % (чистый оттенок). Значение означает яркость пиксела, при этом 0 % соответствует черному цвету, а 100 % – максимально яркому из возможных цветов. Несмотря на то что данная система является улучшением по сравнению с системой RGB, она страдает от той же неравномерности восприятия. Дополнительным усовершенствованием системы HSV является цветовая система HSL, основанная на оттенке, насыщенности и яркости/светлоте. Оттенок и насыщенность функционируют так же, как и в системе HSV. Яркость, напротив, символизирует пропорцию белого или черного, смешанного с цветом, при этом 0 % приходится на черный, 50 % – на чистый цвет, а 100 % – на белый. Несмотря на свою полезность в графическом дизайне и веб-разработке, система HSL, как и система HSV, страдает от отсутствия единообразия восприятия, хотя и в меньшей степени. Цветовая система HCL/LCH, основанная на оттенке, насыщенности и светлоте, – это моя универсальная система для всего, начиная от визуализации данных и заканчивая графическим дизайном. Эта система, нередко именуемая LCH или HCL, в зависимости от области применения, представляет собой значительно улучшенную версию системы HSL, без искажений, связанных с использованием различной насыщенности, и практически однородна по восприятию. В то время как оттенок и яркость ведут себя так же, как в HSL, насыщенность примерно соответствует «количеству цвета» в диапазоне от 0 до 150. Она часто доступна в программном обеспечении, и ее незначительная неоднородность восприятия перевешивается простотой использования. Между тем цветовая система LAB (L*a*b*) представляет собой независимое от устройства цветовое пространство, предназначенное для точного представления цветов на различных устройствах и в различных средах. Цветовая система LAB включает в себя три параметра: L* (яркость/светлота), a* (положение между красным/пурпурным и зеленым) и b* (положение между желтым и синим/циановым). Это сочетание основано на том, как наши глаза воспринимают цвета в этих трех взаимодополняющих парах. В целях более качественной ее иллюстрации попробуйте иллюзию сиреневого охотника, также именуемую иллюзией Pac-Man, чтобы ощутить дополняющий цветовой эффект остаточного изображения. Для того чтобы этого добиться, следите глазами за движением вращающихся сине-фиолетовых (пурпурных) точек, при этом точки должны быть только одного цвета, пурпурного. Теперь смотрите на черную точку × в центре. Пурпурные точки перестают двигаться, и зеленая точка начинает перемещаться по кругу из пурпурных точек. Эта точка зеленая, потому что зеленый цвет дополняет розовый. Смотрите на
Цветовые системы  243 центральную × достаточно долго и уменьшите насыщенность примерно до 20 %, и пурпурные точки должны полностью исчезнуть. Для того чтобы испытать эту иллюзию, посетите веб-страницу по указанному в сноске адресу1. Примечание 22.1. Используемая для расчета различий в восприятии цвета в системе LAB формула CIEDE2000 является, пожалуй, одним из самых причудливых математических уравнений, которые применяются в настоящее время. Обратите на нее внимание! Цветовое пространство LAB часто используется для количественных применений цвета, например в спектрофотометрах, библиотеках цветов, программах редактирования изображений и визуализации данных, благодаря своей способности обеспечивать точное сочетание цветов на различных устройствах и в различных средах. Однако его слишком сложно использовать при ручном определении цвета. Система OKLAB представляет собой цветовое пространство типа LAB, сконструированное таким образом, чтобы быть более однородным с точки зрения восприятия, чем другие варианты LAB, то есть равные расстояния в цветовом пространстве соответствуют равному увеличению воспринимаемой разницы в цветах. Популярность системы OKLAB в области цифрового дизайна и визуализации данных растет благодаря ее повышенной точности и взаимоувязанности цветового представления. Существенным преимущест­ вом системы OKLAB перед другими цветовыми пространствами является то, что для расчета воспринимаемых различий в цвете можно использовать евклидово расстояние. Более глубже понять цветовое пространство OKLAB и другие цветовые пространства помогают блок-посты по OKLAB2 и Colorpicker3, которые дают отличную информацию. Наконец, существуют также системы CMYK и Pantone, которые используются в печати. Для создания цветов в CMYK используются голубой, пурпурный, желтый и черно-белый цвета. При печати необходимо выполнить конвертацию в CMYK, и если вы этого не сделаете, то принтер с этим справится сам. Система сочетания цветов Pantone (Pantone Matching System, аббр. PMS) предлагает стандартизированные, точные цвета для получения стабильных результатов печати. Печать – это совершенно другая вселенная со своими проблемами. Мой совет: просто избегайте чрезмерно насыщенных цветов, и все будет в порядке. Каждая из этих цветовых систем имеет свои уникальные сильные и слабые стороны, выбор зависит от конкретных потребностей проекта4. 1 2 3 4 См. https://michaelbach.de/ot/col-lilacChaser/index.html. См. https://bottosson.github.io/posts/oklab/. См. https://bottosson.github.io/posts/colorpicker/. Для того чтобы понять, как выглядят некоторые из этих пространств, посмотрите вот этот потрясающий ролик: https://youtu.be/HlDySNpGbyc.
244  Цветовые данные 22.2.1. Внимание: цветовые карты могут увеличивать риск смерти! В 1990-х годах специалисты по визуализации данных внедрили радужную цветовую карту, наиболее известным вариантом которой является дефолтная палитра jet. Однако исследователи выразили обеспокоенность по поводу ее неоднородности, из-за которой переходы могут неправильно восприниматься. Обратите внимание, что на рис. 22.15d оттенки серого кажутся плавными и без визуальных разрывов. Напротив, на рис. 22.15a и 22.15c цвета резко меняются, создавая разрывы между ними. (a) Jet (b) Viridis (c) Jet Grayscale (d) Grayscale Рис. 22.15  Опасность радужной цветовой карты (jet) Роговиц и Трейниш [26] выразили обеспокоенность по поводу радужной цветовой карты (или карты цветов радуги), а Борланд и Тейлор Ли [6] выделили дополнительные причины, по которым радужная цветовая карта все-таки считается вредной. Боркин и соавт. [5] провели исследования испытуемых с использованием различных цветовых карт, включая радужную цветовую карту, в контексте медицинской визуализации и продемонстрировали, что однородная по восприятию цветовая карта приводит к меньшему количеству диагнос­ тических ошибок. Проще говоря, использование надлежащей цветовой палит­ ры уменьшает количество диагностических ошибок. Однако Крамери и соавт. [12] пришли к выводу, что неправильное использование цвета все еще сохраняется в науке, подчеркивая важность своевременной корректировки практики. Эти проблемы использования цвета для общения усиливаются при рассмотрении людей, страдающих дальтонизмом. Примерно 8 % всех мужчин и 0,5 % всех женщин страдают дальтонизмом. Существует три главные формы дальтонизма: протанопия (красный), дейтанопия (зеленый) и тританопия (синий), каждая из которых соответствует цветочувствительным колбочкам в наших глазах. Улучшение удобочитаемости цветов предусматривает варьирование их значения и оттенка. Более того, следует избегать использования в графике красного и зеленого цветов, поскольку красно-зеленая цветовая слепота является наиболее распространенной формой. Для того чтобы проверить, подходит ли ваша визуализация для дальтоников, можно воспользоваться симулятором Coblis1. 1 См. https://www.color-blindness.com/coblis-color-blindness-simulator/.
Цветовые системы  245 22.2.2. Итак, что же следует использовать? Простым и правильным решением было бы использовать научную цветовую карту, которая вам нравится, и использовать ее по умолчанию. Если вы хотите выбрать цвета самостоятельно, то следует воспользоваться системой HCL/LCH, поскольку это наиболее интуитивно понятное и простое в использовании пространство для создания цветовых палитр. Возможно, вы также захотите поэкспериментировать с системой OKHSL, дочерним вариантом систем OKLAB и HSL, которая создает визуально однородное пространство HSL. Попробуйте оба варианта и обратите внимание на различия1. Слепота на синий цвет Слепота на зеленый цвет Слепота на красный цвет Рис. 22.16  Пример дальтонизма В качестве общего совета при выборе цветов следует отдавать предпочтение пастельным оттенкам, поскольку они, как правило, более мягкие и создают меньшую нагрузку на глаза. Рекомендуется избегать высокой насыщенности, так как чрезмерно насыщенные цвета могут отвлекать внимание и затенять изображение. Следует быть внимательными к использованию спектральных цветов, так как они могут вызывать остаточные изображения и потенциально искажать восприятие зрителя. Стратегическое использование цвета для группировки и поиска в визуализации может значительно облегчать зрителям навигацию и понимание представленной информации. Умелое применение цвета при визуализации данных улучшает понимание и взаимодействие с данными, тогда как ненадлежащее использование может скрывать важные детали и приводить к путанице. Помощь в процессе поиска дополнительных вариантов цвета и создания палитр могут оказать следующие ниже ресурсы: 1 См. https://bottosson.github.io/misc/colorpicker/.
246  Цветовые данные   Adobe Color1 позволяет создавать цветовые палитры, используя разные правила цветовой гармонии и цветовые режимы. Также есть возможность выбирать цвета из своего изображения, создавать градиенты на изображениях и тестировать их на доступность;   Paletton2 представляет собой фантастический инструмент для создания цветовых палитр;   Color Brewer3 обеспечивает однородность в плане восприятия цветовых схем для карт и визуализации данных;   Color Thief 4 позволяет извлекать цвета из изображения для создания вдохновленных природой палитр;   Viz Palette5 может использоваться для проверки цветовых палитр перед созданием визуализаций. Указанный инструмент позволяет просматривать наборы цветов на примерах графиков, симулировать несовершенства в цвете и изменять цвета в палитре;   Научные цветные карты6 представляет собой коллекцию однородных и удобочитаемых цветных карт для научного использования;   Realtime Colors7 представляет собой инструмент для визуализации и тестирования цветовых палитр на веб-сайтах, позволяющий пользователям эффективно применять и экспортировать цвета в различные форматы. 22.3. Краткий итог В этой главе были рассмотрены вопросы стратегического использования цветовых схем с целью эффективной организации и презентации данных. Независимо от того, проводите ли вы тонкие различия между категориями или смело их противопоставляете, правильное использование цвета может сделать данные более доступными и содержательными. Также были затронуты различные цветовые системы и вопросы важности правильного выбора цветов. В следующей главе будут рассмотрены способы создания эффективных таблиц! 1 2 3 4 5 6 7 См. https://color.adobe.com/create/color-wheel. См. https://paletton.com/. См. http://colorbrewer2.org/. См. https://lokeshdhakar.com/projects/color-thief/. См. https://projects.susielu.com/viz-palette. См. https://www.fabiocrameri.ch/colourmaps/. См. https://realtimecolors.com.
Глава 23 Создание таблиц Честно говоря, не люблю составлять таблицы. Не знаю почему, но они никогда не получаются правильными. Однако пакет gt (от англ. grammar of tables, то есть грамматика таблиц) делает это занятие простым и даже приятным. Поэтому в данной главе мы сосредоточимся на создании простых сводных таблиц с помощью пакета gt. Важно отметить, что пакет gt – это лишь один из многих пакетов, которые служат для создания таблиц; к другим относится пакет kableExtra для построения более сложных таблиц, пакет DT для создания интерактивных таблиц HTML, пакет reactable для построения реактивных таблиц и пакет flextable, среди прочих. В отличие от визуализации и обработки данных, где использование инструментов ggplot, plotly, dplyr и data.table практически является универсальным, предпочтительного пакета для создания таблиц не существует. Поэтому мы остановимся на gt из-за его простоты использования и способности справляться с рядом базовых задач. Пакет gt упрощает создание элегантных, индивидуально настраиваемых таблиц, что делает его универсальным инструментом для отчетов, презентаций и веб-приложений. Примечание 23.1. Спросите десятерых пользователей языка R о предпочтительном пакете для построения таблиц, и вы, скорее всего, получите двадцать разных ответов. 23.1. Таблицы gt Для начала убедитесь, что у вас установлен пакет gt. Мы также будем использовать пакет gtExtras, который расширяет способности пакета gt за счет конкретно-прикладных тем, условного форматирования и многого другого. Кроме того, мы будем использовать пакет emojifont для доступа к эмодзи и подпакет dplyr из tidyverse для манипулирования данными. # install.packages(c("gt","gtExtras","emojifont")) library(dplyr) library(gt) library(gtExtras) library(emojifont)
248  Создание таблиц В качестве примера мы будем использовать встроенный набор данных gtcars, который содержит информацию о различных автомобилях. Давайте взглянем на него с помощью функции gt(). Примечание 23.2. Столбец trim был удален, чтобы таблица поместилась на странице. Части таблицы GT Заголовок Верхний колонтитул таблицы Заглушка колонтитула Подзаголовок Пролет надписи столбца Надпись заглушки колонтитула Надпись столбца Надписи столбцов Ячейка Ячейка Ячейка Ячейка Тело таблицы Надпись столбца Надпись столбца Надпись строки Ячейка Надпись строки Ячейка Надпись группы строк Заглушка Надпись сводки Сводная ячейка Сводная ячейка Сводная ячейка Нижний колонтитул таблицы Подтабличные пояснения Пояснения об источниках Рис. 23.1  Части таблицы GT gt::gtcars %>% select(-trim) %>% dplyr::sample_n(size = 4) %>% gt() mfr Ferrari Porsche Nissan Maserati model California 718 Boxster GT-R Granturismo year 2015 2017 2016 2016 bdy_style convertible convertible coupe coupe hp 553 300 545 454 hp_rpm 7500 6500 6400 7600 trq 557 280 436 384 trq_rpm 4750 1950 3200 4750 mpg_c 16 21 16 13 mpg_h 23 28 22 21 drivetrain rwd rwd awd rwd trsmn 7a 6m 6a 6am ctry_origin Italy Germany Japan Italy msrp 198973 56000 101770 132825 23.1.1. Подготовка данных Пакет gt прекрасно работает с подпакетом dplyr, позволяя использовать привычные глаголы для форматирования таблиц. Давайте начнем с того, что сосредоточимся на лидирующей стране в области автомобильной промышленности – Германии. Мы сгруппируем автомобили по их производителю (mfr) и отсортируем их в зависимости от цены (msrp). При создании таблицы
Таблицы gt  249 параметр rowname_col позволяет указывать столбец в качестве имен строк – в приведенном ниже примере будет использоваться столбец "model". table_grouped <- gt::gtcars %>% select(-trim) %>% filter(ctry_origin == "Germany") %>% # Отфильтровать немецкие автомобили group_by(mfr) %>% # Сгруппировать по производителю arrange(desc(msrp)) %>% # Расположить в нисходящем порядке цены slice_head(n = 2) %>% # Выбрать два верхних автомобиля filter(mfr %in% c("Audi", "BMW")) %>% # Отфильтровать автомобили Audi и BMW gt::gt(rowname_col = "model") # Таблица с моделями авто в качестве имен строк table_grouped Year bdy_style hp Audi R8 S8 BMW i8 M6 hp_rpm trq trq_rpm mpg_c mpg_h drivetrain trsmn ctry_origin msrp 2015 coupe 2016 sedan 430 7900 520 5800 317 4500 481 1700 11 15 20 25 awd awd 6m 8am Germany Germany 115900 114900 2016 coupe 2016 coupe 357 5800 560 6000 420 3700 500 1500 28 15 29 22 awd rwd 6am 7a Germany Germany 140700 113400 Таблица содержит много столбцов, и чтобы сделать ее более удобочитаемой, с помощью функции cols_hide() можно скрыть некоторые столбцы. Зачем использовать функцию cols_hide() вместо удаления столбцов посредством пакета dplyr? Иногда возникает необходимость задействовать столбец в условных инструкциях, но выводить его на экран не требуется. Для того чтобы сгруппировать столбцы, связанные с производительностью, можно воспользоваться функцией cols_move(). Хотя это можно было бы сделать с помощью подпакета dplyr, его интеграция в процесс создания таблицы делает рабочий поток проще. Сгруппированные столбцы можно выделить, добавив пролет (спаннер) для верхнего колонтитула, что выполняется с помощью функции tab_spanner(), указав столбцы и установив надпись. table_span <- table_grouped %>% gt::cols_hide( # Спрятать определенные столбцы columns = c(bdy_style, drivetrain, ctry_origin, trsmn) ) %>% gt::cols_move( # Переместить конкретные столбцы после year columns = c(msrp, trsmn, mpg_c, mpg_h), after = year ) %>% gt::tab_spanner( # Создать пролет для верхнего колонтитула columns = c(mpg_c, mpg_h, hp, hp_rpm, trq, trq_rpm), label = "Performance" ) table_span
250  Создание таблиц Year msrp Audi R8 S8 BMW i8 M6 Performance mpg_c mpg_h hp hp_rpm trq trq_rpm 2015 115900 11 2016 114900 15 20 25 430 7900 520 5800 317 4500 481 1700 2016 140700 28 2016 113400 15 29 22 357 5800 560 6000 420 3700 500 1500 Иногда возникает потребность объединить пары соотнесенных столбцов в один столбец. Для этого можно воспользоваться функцией cols_merge(). Мы объединим мощность двигателя (hp) с соответствующими оборотами в минуту (hp_rpm), крутящий момент (trq) с соответствующими оборотами в минуту (trq_rpm), а городские мили на галлон (mpg_c) с автомобильными милями на галлон (mpg_h). Указанная функция принимает столбцы (columns), на которые можно ссылаться в тексте (text) с помощью {#} у столбцов. Поскольку мы работаем с HTML-таблицами, то можно использовать HTML-теги, в частности <br> для добавления разрыва строки. В качестве альтернативы в документах LaTeX/PDF можно использовать \shortstack{{1} {2}} или, что еще лучше, \makecell{{1} {2}} из пакета LaTeX makecell. Обратите внимание, что в объединенном столбце будет использоваться название первого столбца, а надписи носят чисто косметический характер и не могут использоваться в качестве ссылок. Затем используется функция cols_label(), чтобы назначить индивидуальные надписи столбцам, используя синтаксис column_name = "column_label". table_merge <- table_span %>% # Объединить столбцы мощности двигателя (hp) и оборотов в минуту (hp_rpm) cols_merge(columns = c(hp, hp_rpm), pattern = "{1}<br>@{2}rpm") %>% # Объединить столбцы крутящего момента (trq) и обороты в минуту (trq_rpm) cols_merge(columns = c(trq, trq_rpm), pattern = "{1}<br>@{2}rpm") %>% # Объединить столбцы городских милей на галлон (mpg_c) и автомилей (mpg_h) cols_merge(columns = c(mpg_c, mpg_h), pattern = "{1}c<br>{2}h") %>% cols_label( # Задать конкретно-прикладные надписи конкретным столбцам year = "Year", msrp = "MSRP", mpg_c = "MPG", hp = "Horsepower", trq = "Torque" ) table_merge
Таблицы gt  251 Year MSRP Audi R8 2015 115900 S8 2016 114900 BMW i8 2016 140700 M6 2016 113400 Performance MPG Horsepower Torque 11c 20h 15c 25h 430 @7900rpm 520 @5800rpm 317 @4500rpm 481 @1700rpm 28c 29h 15c 22h 357 @5800rpm 560 @6000rpm 420 @3700rpm 500 @1500rpm Пакет gt предоставляет целый ряд функций форматирования fmt_*(), которые широко применяются для настройки внешнего вида числовых и текстовых столбцов. Например, можно настроить вывод валюты в столбце msrp в долларах США без десятичных знаков. С помощью функции cols_align(), позволяющей выбирать столбцы и устанавливать выравнивание по правому краю, левому краю или центру, можно настроить выравнивание столбцов. Поскольку объединенные столбцы выглядят громоздкими из-за двух строк, можно уменьшить размер текста, используя функцию tab_style(). В указанной функции используется определение стиля, предоставляемое вспомогательными функциями, такими как cell_styles(), которые включают информацию о поддерживаемом стиле. В приведенном ниже примере применяется функция cell_text(), чтобы задать размер текста равным 12 пикселам ("12px"). Во втором аргументе, locations, используется еще одна вспомогательная функция из семейства cells_*(). Для того чтобы определить целевые клетки в теле таблицы, используется функция cells_body(), которая применяется к столбцам mpg_c, hp и trq. Для того чтобы дополнить таблицы цветом, можно воспользоваться функцией data_color, которая поддерживает создание простого градиента или применение сплошного цвета к данным. Указанная функция может конкретизировать область (domain) и использовать готовые палитры. Дополнительную функциональность обеспечивает функция gt_color_rows() из пакета gtExtras. Для получения дополнительной информации обратитесь к документации пакета. table_format <- table_merge %>% # Отформатировать столбец msrp как валюту fmt_currency(columns = msrp, decimals = 0, currency = "USD") %>% # Выровнять конкретные столбцы по центру cols_align(columns = c(mpg_c, hp, trq), align = "center") %>% tab_style( # Применить стиль текста ячейки к конкретным столбцам style = cell_text(size = "12px"), locations = cells_body(columns = c(mpg_c, hp, trq)) ) %>% # Применить управляемую данными цветовую шкалу к столбцу msrp data_color(columns = msrp, colors = c("white", "aquamarine"))
252  Создание таблиц table_format Year MSRP Performance MPG Horsepower Torque Audi R8 2015 $115 900 11c 20h S8 2016 $114 900 15c 25h BMW i8 2016 $140 700 28c 29h M6 2016 $113 400 15c 22h 430 @7900rpm 520 @5800rpm 317 @4500rpm 481 @1700rpm 357 @5800rpm 560 @6000rpm 420 @3700rpm 500 @1500rpm Теперь таблица выглядит вполне прилично! С помощью функции tab_hea­ der() ей можно дать название «German Automobiles» (Немецкие автомобили) и подзаголовок с эмодзи. Для того чтобы пояснить термин «MSRP» читателям, которые, возможно, не знают его значения, можно применить подтаб­ личное пояснение. Подтабличные пояснения можно добавлять к отдельным ячейкам, указывая номер строки либо используя выражения – в данном случае самым дорогим автомобилем является BMW i8, который также является электрическим! Как и в случае с функцией tab_style(), необходимо указать местоположение и текст пояснения. Не забудьте добавить свой источник данных; это можно сделать с помощью функции tab_source_note(). Обертывание текста в функцию md() позволяет использовать синтаксис упрощенной разметки Markdown для целей форматирования, включая добавление ссылок. table_header <- table_format %>% # Добавить заголовок и подзаголовок с эмодзи tab_header( title = "German Automobiles", subtitle = paste0("These are some nice ", emojifont::emoji("car"), "s") ) %>% # Добавить подтабличное пояснение, чтобы разъяснить смысл термина MSRP tab_footnote( locations = cells_column_labels(columns = msrp), footnote = "Manufacturer's Suggested Retail Price in USD" ) %>% # Добавить подтабличное пояснение для самой дорогой автомашины tab_footnote( locations = cells_body(msrp, msrp == max(msrp)), footnote = "Electric cars used to be expensive" ) %>% # Добавить пояснение, чтобы процитировать источник данных tab_source_note(source_note = md("Source: **gtcars** [dataset from gt package](https://gt.rstudio.com/articles/gt-datasets.html)")) table_header
Таблицы gt  253 German Automobiles These are some nice s Year MSRP1 Audi R8 2015 $115 900 S8 11c 20h 15c 25h 430 @7900rpm 520 @5800rpm 317 @4500rpm 481 @1700rpm $140 700 28c 29h 2016 $113 400 15c 22h 357 @5800rpm 560 @6000rpm 420 @3700rpm 500 @1500rpm 2016 $114 900 BMW i8 2016 M6 Performance MPG Horsepower Torque 2 Manufacturer’s Suggested Retail Price in USD. Electric cars used to be expensive. Source: gtcars dataset from gt package. 1 2 Для того чтобы сделать таблицы gt еще более совершенными, можно применить темы, используя пакет gtExtras. Этот пакет предлагает целый ряд готовых тем, которые можно легко добавлять в таблицы. После установки и загрузки пакета gtExtras можно применить одну из его тематических функций, применив конкретный стиль к таблице. Давайте добавим тему, аналогичную теме веб-сайта FiveThirtyEight1. # Добавить тему Five Thirty Eight в таблицу (table_themed <- table_header %>% gtExtras::gt_theme_538()) German Automobiles These are some nice s Year MSRP1 Audi R8 2015 $115 900 S8 11c 20h 15c 25h 430 @7900rpm 520 @5800rpm 317 @4500rpm 481 @1700rpm $140 700 28c 29h 2016 $113 400 15c 22h 357 @5800rpm 560 @6000rpm 420 @3700rpm 500 @1500rpm 2016 $114 900 BMW i8 2016 M6 Performance MPG Horsepower Torque 2 Manufacturer’s Suggested Retail Price in USD. Electric cars used to be expensive. Source: gtcars dataset from gt package. 1 2 1 См. https://projects.fivethirtyeight.com/.
254  Создание таблиц Создав красивую таблицу, скорее всего, возникнет желание ее сохранить. Хотя прямого способа сохранения в Excel не существует, пакет gt поддерживает сохранение таблицы в различных других форматах, таких как .html для встраивания в веб-сайты или электронные письма, .png для изображений, .tex для документов LaTeX, .pdf для PDF-файлов и .docx для документов Microsoft Word. В целях улучшения удобства использования и внешнего вида сохраненных таблиц можно применять дополнительные опции. Например, сохранение таб­лицы gt в виде HTML-файла с параметром inline_css = TRUE широко используется при встраивании таблицы в электронное письмо в формате HTML, обеспечивая применение стилей непосредственно в электронном письме. Без этой опции в HTML-файл будут встроены стили каскадных таблиц стилей (CSS). При сохранении таблицы в формате PNG создается обрезанное изображение HTML-таблицы. Используя опцию развертывания, можно изменить размер пустого пространства вокруг изображения, что позволит улучшить наглядное представление и интегрировать его в другие документы или презентации. Примечание 23.3. Обратите внимание, что для сохранения в некоторых форматах потребуется установить пакет webshot2. gtsave(table_themed, filename = "tab_1.html", inline_css = TRUE) gtsave(table_themed, "tab_1.png", expand = 10) gtsave(table_themed, "tab_1.tex") gtsave(table_themed, "tab_1.pdf") gtsave(table_themed, "tab_1.docx") И окончательный результат будет выглядеть примерно так: library(dplyr) library(gt) library(gtExtras) library(emojifont) gt::gtcars %>% select(-trim) %>% filter(ctry_origin == "Germany") %>% group_by(mfr) %>% arrange(desc(msrp)) %>% slice_head(n = 2) %>% filter(mfr %in% c("Audi", "BMW")) %>% gt::gt(rowname_col = "model") %>% gt::cols_hide( columns = c(bdy_style, drivetrain, ctry_origin, trsmn) ) %>% gt::cols_move( columns = c(msrp, trsmn, mpg_c, mpg_h), after = year ) %>% gt::tab_spanner( columns = c(mpg_c, mpg_h, hp, hp_rpm, trq, trq_rpm), label = "Performance"
Таблицы DT  255 ) %>% cols_merge(columns = c(hp, hp_rpm), pattern = "{1}<br>@{2}rpm") %>% cols_merge(columns = c(trq, trq_rpm), pattern="{1}<br>@{2}rpm") %>% cols_merge(columns = c(mpg_c, mpg_h), pattern = "{1}c<br>{2}h") %>% cols_label( year = "Year", msrp = "MSRP", mpg_c = "MPG", hp = "Horse Power", trq = "Torque" ) %>% fmt_currency(columns = msrp, decimals = 0, currency = "USD") %>% cols_align(columns = c(mpg_c, hp, trq), align = "center") %>% tab_style( style = cell_text(size = "12px"), locations = cells_body(columns = c(mpg_c, hp, trq)) ) %>% data_color(columns = msrp, colors = c("white", "aquamarine")) %>% tab_header( title = "German Automobiles", subtitle = paste0("These are some nice ", emojifont::emoji("car"), "s") ) %>% tab_footnote( locations = cells_column_labels(columns = msrp), footnote = "Manufacturer's Suggested Retail Price in USD" ) %>% tab_footnote( locations = cells_body(msrp, msrp == max(msrp)), footnote = "Electric cars used to be expensive" ) %>% tab_source_note(source_note = md("Source: **gtcars** [dataset from gt package](https://gt.rstudio.com/articles/gt-datasets.html)")) %>% gtExtras::gt_theme_538() 23.2. Таблицы DT Когда возникает потребность сделать презентацию данных важным заинтересованным сторонам, статических HTML-таблиц иногда бывает недостаточно. Для таких ситуаций отличным решением может стать пакет DT на языке R, поскольку он позволяет включать интерактивные таблицы в отчеты или аналитические материалы. Пакет DT представляет собой интерфейс к биб­лиотеке JavaScript DataTables. Это гибкий инструмент для вывода на экран данных в таблицах с массой возможностей по индивидуальной настройке. В отличие от пакета gt, который больше предназначен для создания таблиц, готовых к публикации, пакет DT действительно всецело касается придания таблицам интерактивности с целью более углубленного разведывательного анализа данных, так как позволяет сортировать, фильтровать и разбивать таблицы
256  Создание таблиц на страницы, что действительно полезно при работе с крупными наборами данных. В нем также есть такие функциональные средства, как фильтры для отдельных столбцов и возможность скрывать или изменять порядок следования столбцов. Кроме того, есть несколько вариантов презентации данных. Давайте посмотрим, как использовать пакет DT для создания таблицы с набором данных о немецких автомобилях: library(DT) german_cars <- gt::gtcars %>% filter(ctry_origin == "Germany") %>% select(mfr, model, year, trim, bdy_style, hp) DT::datatable( german_cars, extensions = "Buttons", # Активировать расширение для работы с кнопками options = list( dom = "Bfrtip", # Элементы управления таблицей и их порядок следования buttons = c("copy", "csv", "excel", "pdf", "print"), pageLength = 5, # Количество строк в расчете на страницу autoWidth = TRUE, # Скорректировать ширину столбца order = list(list(1, "asc")), # Начальный порядок сортировки searching = TRUE, # Активировать поиск searchHighlight = TRUE, # Выделять поисковые совпадения lengthChange = TRUE # Разрешить изменение записей постранично ) ) Рис. 23.2  Пример таблицы DT
Краткий итог  257 23.3. Краткий итог В этой главе был рассмотрен пример создания таблицы на языке R с использованием пакета gt на основе встроенного набора данных gtcars с описанием способов манипулирования данными, их стилизации и тематизации. Вдобавок был представлен пакет DT, служащий для построения интерактивных таблиц. На данный момент вы должны быть во всеоружии, чтобы приступить к реализации собственного проекта!
Эпилог В области науки данных и аналитики путь к совершенству – это не спринтерская дистанция, а настоящий марафон. Приобретение навыков и инструментов не выливается в разовое мероприятие; это непрерывный путь разведывательного анализа, любопытства и роста. Подобно мастерам боевых искусств, которые не прекращают тренировки после получения черного пояса, энтузиасты информационных технологий не прекращают обучение, как только овладевают основополагающими инструментами. Черный пояс означает начало истинного мастерства, а не его кульминацию. В нашем быстро меняющемся мире есть соблазн сосредоточиваться на сиюминутных выгодах, стремиться к быстрым победам, которые продвинут нас вперед в краткосрочной перспективе. Но настоящий опыт, который отличает вас от других и позволяет вносить значимый вклад, требует более дальновидного подхода. Он требует, чтобы мы заглядывали за горизонт следующего месяца и представляли, где мы хотим быть через пять лет или даже десятилетие. Отправляясь в это путешествие, следует помнить, что сфера науки о данных постоянно эволюционирует. Появляются новые инструменты, адаптируются методологии, а вопросы, на которые мы стремимся найти ответы, становятся все более сложными. Включайтесь в непрерывный процесс обучения, развивайте свою любознательность и ориентируйтесь на долгосрочную перспективу, поскольку в этой области целью является само путешествие, и каждый ваш шаг обогащает ваше понимание и опыт.
Справочные материалы [1] Когда следует корректировать стандартные ошибки для выполнения кластеризации? Abadie A, Athey S, Imbens G, Wooldridge J (2017) When should you adjust standard errors for clustering? NBER p w24003. https://doi. org/10.3386/w24003. http://www.nber.org/papers/w24003.pdf. [2] Модели панельных данных с интерактивными фиксированными эффектами. Bai J (2009) Panel data models with interactive fixed effects. Econometrica 77(4):1229–1279. https://doi.org/10.3982/ecta6135. MAG ID: 2128249713. [3] 1500 ученых проливают свет на воспроизводимость. Baker M (2016) 1,500 scientists lift the lid on reproducibility. Nature 533(7604):452–454. https:// doi.org/10.1038/533452a. https://www.nature.com/articles/533452a. [4] За точкой перелома? Достаточность опросов в консолидированных экспериментах. Bansak K, Hainmueller J, Hopkins DJ, Yamamoto T (2021) Beyond the breaking point? Survey satisficing in conjoint experiments. Polit Sci Res Methods 9(1):53–71. [5] Оценивание визуализации артерий для диагностики сердечных заболеваний. Borkin M, Gajos K, Peters A, Mitsouras D, Melchionna S, Rybicki F, Feldman C, Pfister H (2011) Evaluation of artery visualizations for heart disease diagnosis. IEEE Trans Visualiz Comput Graph 17(12):2479–2488. https://doi. org/10.1109/TVCG.2011.192. http://ieeexplore.ieee.org/document/6065015/. [6] Радужная цветовая карта (по-прежнему) считается вредной. Borland D, Taylor Ii RM (2007) Rainbow color map (still) considered harmful. IEEE Comput Graph Appl 27(2):14–17. https://doi.org/10.1109/MCG.2007.323435. https://ieeexplore.ieee.org/document/4118486/. [7] Организация данных в электронных таблицах. Broman KW, Woo KH (2018) Data organization in spreadsheets. Am Stat 72(1):2–10. https://doi.org/10.10 80/00031305.2017.1375989. https://www.tandfonline.com/doi/full/10.1080/00 031305.2017.1375989. [8] Справочник по маркетинговым шкалам: многопозиционные показатели для исследования понимания потребителей. Bruner GC (2019) Marketing scales handbook: multi-item measures for consumer insight research, vol 10. GCBII Productions, LLC, Fort Worth. [9] Mice: многопеременные вычисления с помощью цепных уравнений на языке R. Buuren S, Groothuis-Oudshoorn C (2011) Mice: multivariate imputation by chained equations in R. J Stat Softw 45:1–67. https://doi.org/10.18637/ jss.v045.i03.
260  Справочные материалы [10] Путь Тьюринга: руководство по воспроизводимым, этичным и совместным исследованиям. Community TTW (2022) The turing way: a handbook for reproducible, ethical and collaborative research. Zenodo. https://doi. org/10.5281/ZENODO.3233853. https://zenodo.org/record/3233853. [11] «Рычаги» для построения графиков. Contgreave A (2022) The “Levers” of Chart-Making. https://www.linkedin.com/pulse/levers-chart-making-andycotgreave/. [12] Неправильное использование цвета в научной коммуникации. Crameri F, Shephard GE, Heron PJ (2020) The misuse of colour in science communication. Nat Commun 11(1):5444. https://doi.org/10.1038/s41467-02019160-7. https://www.nature.com/articles/s41467-020-19160-7. [13] Сравнительная эффективность некоторых распространенных символов с градуированными точками при представлении количественных данных. Flannery JJ (1971) The relative effectiveness of some common graduated point symbols in the presentation of quantitative data. Cartograph Int J Geograph Inf Geovisualiz 8(2):96–109. https://doi.org/10.3138/J647-1776745H-3667. https://utpjournals.press/doi/10.3138/J647-1776-745H-3667. [14] Методология опроса. Groves RM, Fowler Jr FJ, Couper MP, Lepkowski JM, Singer E, Tourangeau R (2011) Survey methodology. Wiley, Hoboken. [15] Восприятие в визуализации. Healey CG (2012) Perception in visualization. https://www.csc2.ncsu.edu/faculty/healey/PP/#jscript_search. [16] Давайте начнем | Счастливые Git и GitHub для пользователя R. Hester J (2023) Let’s Git started | Happy Git and GitHub for the useR. Self-Published. https://happygitwithr.com/. [17] Отсев участников в зависимости от продолжительности опроса в университетских учебных работах, проводимых при посредничестве интернета: последствия для постановки учебного исследования и добровольного участия в психологических исследованиях. Hoerger M (2010) Participant dropout as a function of survey length in internet-mediated university studies: implications for study design and voluntary participation in psychological research. Cyberpsychol Behavior Soc Netw 13(6):697–700. Mary Ann Liebert, New Rochelle. [18] Когда и как следует использовать множественное восполнение для обработки пропущенных данных в рандомизированных клинических исследованиях: практ. руководство с блок-схемами. Jakobsen JC, Gluud C, Wetterslev J, Winkel P (2017) When and how should multiple imputation be used for handling missing data in randomised clinical trials – a practical guide with flowcharts. BMC Med Res Methodol 17(1):162. https://doi. org/10.1186/s12874-017-0442-1. https://bmcmedresmethodol.biomedcentral. com/articles/10.1186/s12874-017-0442-1. [19] Опросы, которые работают: практ. руководство по разработке и проведению более эффективных опросов. Jarrett C (2021) Surveys that work:
Справочные материалы  261 a practical guide for designing and running better surveys. Rosenfeld Media, Brooklyn. [20] Незнакомцы в самолете: контекстно-зависимая готовность к разглашению конфиденциальной информации. John LK, Acquisti A, Loewenstein G (2011) Strangers on a plane: context-dependent willingness to divulge sensitive information. J Consumer Res 37(5):858–873. [21] Размышления, быстрые и медленные. Kahneman D (2011) Thinking, fast and slow, 1st edn. Farrar, Straus and Giroux, New York. [22] Пэлгрейвское руководство по исследованиям опросов. Krosnick JA (2018) Questionnaire design. In: The palgrave handbook of survey research, pp 439–455. Springer, Heidelberg. [23] Влияние вариантов ответа «нет мнения» на качество данных: снижение отрицательного отношения или приглашение к удовлетворенности? Krosnick JA, Holbrook AL, Berent MK, Carson RT, Michael Hanemann W, Kopp RJ, Cameron Mitchell R, Presser S, Ruud PA, Kerry Smith V (2002) The impact of “no opinion” response options on data quality: non-attitude reduction or an invitation to satisfice? Public Opin Quarterly 66(3):371–403. [24] Одинаковые статистики, разные графики: генерирование наборов данных с различным внешним видом и идентичными статистиками с помощью метода симулированного закаливания (имитации отжига). Matejka J, Fitzmaurice G (2017) Same stats, different graphs: generating datasets with varied appearance and identical statistics through simulated annealing. In: Proceedings of the 2017 CHI conference on human factors in computing systems, pp 1290–1294. https://doi.org/10.1145/3025453.3025912, Citation Key: Inproceedings. [25] Логика научного открытия. Popper K (2002) The logic of scientific discovery. ISSR library, Routledge. https://books.google.com/books?id=Yq6xeupNStMC. Citation Key: popper2002logic tex.lccn: 92241375. [26] Визуализация данных: конец радуги. Rogowitz B, Treinish L (1998) Data visualization: the end of the rainbow. IEEE Spectrum 35(12):52–59. https:// doi.org/10.1109/6.736450. https://ieeexplore.ieee.org/document/736450/. [27] Когнитивная нагрузка как руководство: 12 спектров, чтобы улучшить визуализацию данных. Sibinga E, Waldron E (2021) Cognitive load as a guide: 12 spectrums to improve your data visualizations | nightingale. https://nightingaledvs.com/cognitive-load-as-a-guide-12-spectrums-to-improve-your-data-visualizations/. [28] Какая научная идея готова к уходу на пенсию? Stodden V (2014) 2014: What scientific idea is ready for retirement? Edgeorg. https://www.edge.org/ responsedetail/25340. Citation Key: Victoria2014Reproducibility. [29] Психология ответа из опроса. Tourangeau R, Rips LJ, Rasinski K (2000) The psychology of survey response. Cambridge University Press, Cambridge.
262  Справочные материалы [30] Характеристико-интеграционная теория внимания. Treisman A, Gela­ de G (1980) A feature-integration theory of attention. Cognitive Psycholo. [31] Визуальное отображение количественной информации. Tufte ER (2001) The visual display of quantitative information, 2nd edn. Graphics Press, Cheshire. [32] Привязка ответов по шкале Лайкерта. Vagias WM (2006) Likert-type scale response anchors. Clemson International Institute for Tourism & Research Development, Department of Parks, Recreation and Tourism Management Clemson University. [33] Оценка удовлетворенности опросом: влияние на качество данных немотивированных ответов на вопросы анкеты. Vriesema CC, Gehlbach H (2021) Assessing survey satisficing: the impact of unmotivated questionnaire responding on data quality. Edu Res 50(9):618–627. [34] Визуализация информации: восприятие для конструктивного исполнения. Ware C (2021) Information visualization: perception for design, 4th edn. Morgan Kaufmann, Cambridge. [35] Многослойная грамматика графики. Wickham H (2010) A layered grammar of graphics. J Comput Graph Stat 19(1):3–28. https://doi.org/10.1198/ jcgs.2009.07098. Taylor I& Francis tex.eprint: https://doi.org/10.1198/ jcgs.2009.07098 Citation Key: Hadleygrammar2010. [36] Упорядоченные данные. Wickham H (2014) Tidy data. J Stat Softw 59(10). https://doi.org/10.18637/jss.v059.i10. [37] Какова оптимальная продолжительность опроса для онлайновых исследований? Wigmore S (2022) What is a good survey length for online research? https://www.kantar.com/north-america/inspiration/research-services/ what-is-a-good-survey-length-for-online-research-pf. [38] Грамматика графики. Wilkinson L (1999) The grammar of graphics. Statistics and computing. Springer New York. https://books.google.com/ books?id=5boZAQAAIAAJ.
Предметный указатель Символы P .gitignore, файл, 102 Posit (RStudio), 24 G Q Git и GitHub команды add/commit/push/pull, 101 контроль версий. См. Система контроля версий морское судно и морской хаб, 99 репозитории, 100 файл .gitignore, 102 Google Документы, 135 gtcars, набор данных встроенный, 248 Quarto, 130, 132 визуальный режим, 127 документация по таблицам, 128 стиль WYSIWYG, 127 файлы .qmd/командная оболочка, 125 функциональные средства, 126 шаблоны/заготовки, 137 TinyTeX, 126 J janitor, пакет функции convert_to_date()/convert_to_ datetime(), 52 функция clean_names(), 50 функция remove_constant(), 51 функция remove_empty(), 51 функция row_to_names(), 52 K k ближайших соседей (kNN), 77 knitr, пакет, 130 L lubridate, пакет, 40 O OpenAI, документация, 184 R R, язык программирования. См. Интерфейс прикладного программирования (API) анализ данных, 24 манипулирование данными. См. Манипулирование данными основополагающие понятия, 24 пакеты, 24 полный перечень базовых арифметических операций, 25 типы/классы данных, 26 функция str(), 27 tidyverse (readr), 24 renv (воспроизводимая среда) виртуальные машины, 93 изображение рабочего потока, 92 изоляция, 92 исследования в области вычислений, 93 контейнеризация, 93
264  Предметный указатель переносимость, 92 T trackdown, пакет, 135 Y YAML (Еще один язык разметки), 124 Z Zotero, 130, 133 А Анализатор исходного кода статический (lintr), 109 Б Бернейс Эдвард, 151 В Валидация данных, 64 Валидация точная (pointblank) валидационные конвейеры, 67 изображение рабочего потока, 67 исполнение, 67 конкретизация, 67 Визуализация библиотека Echarts, 212 грамматика графики гистограмма, 202 графические интерфейсы, 208 диаграмма рассеяния и столбчатый график, 202 интерфейс построения графиков Excel, 202 пользовательский интерфейс пакета esquisse, 208 пользовательский интерфейс пакета ggThemeAssist, 208 слой геометрии, 205 слой данных, 203 слой темы, 207 слой фасет, 207 слой эстетики, 204 статистические преобразования, 206 функция ggplot(), 202 шкалы, 205 элементы/соотнесения, 202 грязная дюжина из пакета datasauRus, 200 интерактивность, 210 объяснительная, 200 основы атрибуты, 197 восприятие, 188 графики, 197 графическое представление информации, 188 каркас когнитивной нагрузки, 198 кодирование, 196 чернила данных, 197 оценивание графиков, 197 пакет echarts4r, 212 разведывательная, 200 разведывательный анализ данных, 200 функция ggplotly(), 210 функция plot_ly(), 211 HTML-виджеты, 211 Восполнение многопеременное с помощью цепных уравнений (MICE), 81 Восполнение множественное модель анализа, 80 Наилучший сценарий из наихудших и наихудший сценарий из наилучших, 79 начальная стадия, 80 пакет mice, 81 статистические методы, 80 Г График вертикальные столбчатые графики, 215 гистограммы, 216 график дождевых облаков, 221 графики временных рядов водопадные/мостовые графики, 229 линейный график, 229 графики плотности, 217 графики по краям, 222 категории/группы, 214
Предметный указатель  265 коробчатый график, 219 корреляция диаграмма рассеяния, 227 коррелограммы, 227 леденцовый график, 215 межквартильный диапазон (IQR), 219 многоугольник частот, 218 пропорции/композиция вафельный график, 226 древовидная карта, 226 круговые графики, 224 многослойный столбчатый график, 223 обычный столбчатый график, 223 пулевой график, 215 распределение, 216 скрипичные графики, 219 столбчатый график, 214 ульевый график, 220 чистый коэффициент потребительской лояльности (NPS), 216 Д Данные упорядоченные (tidyverse) наложенные данные, 42 пакет janitor, 50 пакет tidyr функции separate()/unite(), 47 функции tibble()/tribble(), 49 функция pivot_longer(), 45 функция pivot_wider(), 46 панельные/беспорядочные длинные/обособленные данные, 42 стиль, 106 формоподобная структура, 44 широкие и длинные, 42 readr, 24 Документирование администрирование, 170 иерархическая структура документации, 163 коммуникация, 173 принципы, 161 физическая и электронная документация, 165 финансовая отчетность в научных исследованиях, 171 электронные таблицы, 166 ввод данных, 168 организация, 167 З Закон Стивенса, 195 И Идентификатор цифрового объекта (DOI), 133 Интерфейс прикладного программирования (API), 175 запрос методом DELETE, 175 запрос методом GET, 175 запросы методами POST/PUI/PATCH, 175 модель whisper, 186 определение, 175 пакет qualtRics, 180 службы Google, 182 типы запросов, 175 унифицированные указатели ресурсов, 176 функция request(), 178 OpenAI, 184 Qualtrics, 180 Исследование научное воспроизводимое исчерпывающая документация, 88 обобщаемость, 87 повторяемость/надежность, 87 поток грамотного программирования, 89 разные типы, 87 среды, 91 статистическая модель, 88 К Код исходный модульный модули, 114 несколько файлов, 113 переменные/функции, 111 подход на основе предназначений, 112 реиспользование функций, 111 система экспорта и импорта, 114 функция source(), 112 функция use(), 114
266  Предметный указатель методы на основе деревьев, 78 набор данных airquality, 74 регрессия, 77 фиксированное значение, 75 функция complete(), 72 функция nesting(), 74 функция vis_miss, 74 k ближайших соседей (kNN), 77 пропущенные данные, 70 разные результаты работы методов, 84 статистические методы, 70 Л Лес случайный. См. Метод на основе деревьев Линтер. Анализатор исходного кода статический (lintr) М Макетирование/справочные материалы блоки div, 131 диаграммы, 132 код pagebreak, 132 пакет knitr, 130 функциональные средства/литература, 130 цитирование, 133 Mermaid/Graphviz, 132 Манипулирование данными, 24 матричные игры Равена, 28 пакет lubridate функции ymd(), md(), hms(), ymd_hms(), 40 year(), month(), day(), 41 управление (dplyr) аргумент .by, 36 функция arrange(), 32 функция case_match (), 34 функция count(), 38 функция filter(), 31 функция group_by(), 34 функция mutate(), 33 функция rename(), 38 функция row_number(), 39 функция rowwise(), 37 функция select(), 30 функция skim(), 39 функция summarize(), 34 функция ungroup(), 35 функция read.csv(), 28 Метод на основе деревьев, 78 Модель восполнения множественный процесс, 80 наилучший сценарий из наихудших и наихудший сценарий из наилучших, 79 обработка пропущенных данных заполнение данными, 76 метод восполнения средним или медианным значением, 76 Н Неслучайный пропуск данных (MNAR), 71 О Обзор научных публикаций библиотека Zotero, 118 поиск, 117 управление справочными материалами, 118 чтение, 119 эфективное ведение заметок, 120 ChatGPT, 120 Оболочка командная навигация по каталогам, 95 терминал/интерфейс командной строки, 95 nano, 96 Объяснительность и разведывательность, 200 Операция соединения внешние соединения внутреннее соединение, 59 левое соединение, 57 полное соединение, 59 правое соединение, 58 таблицы, 56 фильтрация антисоединение, 60 полусоединение, 61 Оптимизация совместной работы, 135 Ошибка опроса суммарная (TSE) влияние порядка следования вопросов, 150 компоненты, 141
Предметный указатель  267 методы проведения физических опросов, 157 ошибка в измерении, 141 ошибка в спецификации, 141 платформы для проведения цифровых опросов, 158 платформы для рекрутирования участников, 159 понятное для человека определение, 140 представление ответы, 146 ошибки в выборке, 142 ошибки в охвате, 142 ошибки отсутствия ответов, 142 принципы, 143 репрезентативность, 143 усилие/вознаграждения/ укрепление доверия, 147 продолжительность опроса, 155 разработка вопросов варианты «не знаю» и «затрудняюсь ответить», 154 итеративное составление вопросов, 157 ответы на вопросы, 148 приглашение к опросу, 156 разные типы вопросов, 152 разработчики опросов, 155 рекомендации, 150 соображения, 150 форматы вопросов, 152 шкалы Лайкерта, 153 Эдвард Бернейс, 151 формальное определение, 140 П Пакет табличный пакет DT, 255 Полностью случайный пропуск данных (MCAR), 70 Поток грамотного программирования, 88 Продукт валовой внутренний (ВВП), 231 Процесс валидации инспекция данных вручную, 64 мусор на входе, мусор на выходе, 64 улаживание проблем с данными исполнение скрипта, 65 пакет assertr, 65 пакет pointblank, 67 функции потока управления, 65 функции verify()/assert()/insist(), 65 Р Работа совместная. См. Оптимизация совместной работы Редактор LaTeX, 123 WYSIWYG (что видите, то и получаете), 122 Реляционные структуры визуализация, 61 внешние ключи (ВК), 56 диаграмма сущностейвзаимоотношений, 61 кардинальность, 54, 62 операция соединения, 56 отношение «многие ко многим», 55 отношение «один к одному», 54 отношение «один ко многим», 55 отношение покупатель–заказ, 62 первичный ключ (ПК), 56 С Система документирования ввод данных/организация, 168 коммуникация, 173 основополагающие принципы защищенность и конфиденциальность, 162 иерархическая структура, 163 избыточность, 162 конструктивное исполнение/форматирование, 161 обучение/поддержка, 162 протоколы своместной работы, 162 уровень площадки, 163 устойчивость, 162 централизация, 162 процесс администрирования, 170 регистрация данных, 168 физический и электронный форматы, 165 финансовая отчетность, 171
268  Предметный указатель электронные таблицы, 166 Система контроля версий ветвление, 99 впечатляющая модель, 98 моментальные снимки, 98 репозитории, 100 система резервного копирования, 99 совместная работа, 99 файл .gitignore, 102 Git и GitHub, 99 Система предвнимательная закон Стивенса, 195 замкнутость, 191 иерархия признаков, 192 интегральность и отделимость, 193 нелинейное восприятие, 194 обнаружение границ, 189 обнаружение мишени, 189 одновременный анализ, 189 отслеживание участка, 189 подсчет и оценивание, 189 принципы гештальта, 190 Система сочетания цветов Pantone (PMS), 243 Система цветовая аналогичная/триадическая гармония, 234 взаимодополняющая гармония, 232 двойная взаимодополняющая схема, 237 евклидово расстояние, 241 единообразное восприятие, 239 красный, зеленый, синий (RGB), 240 оттенок, насыщенность/хроматичность, яркость/светлота (HCL), 241 положительная/отрицательная коннотация, 232 предварительно созданные шкалы viridis, 239 прямоугольная или квадратная схема, 237 ресурсы, 245 симулятор Coblis, 244 система LAB, 242 слепота/дальтонизм, 239 схема последовательных цветов, 238 схемы с расходящимися цветами, 239 цветовое колесо, 232 цветовые карты, 244 центр внимания, 233 Случайный пропуск данных (MAR), 70 Смещение систематическое, 71, 145 Специалист в Microsoft Office (MOS), 122 Среда вычислительная, 93 Среда разработки интегрированная (IDE) проект Quarto, 137 рабочий поток совместной работы, 136 файл .gitignore, 102 Стиль статический анализатор исходного кода, 109 форматировщик, 109 tidyverse длинные функции, 108 комментарии, 107 отступы, 106 пакет gt пакет emojifont, 247 пакет gtExtras, 247, 251 пакет webshot2, 254 подпакет dplyr, 248 процесс вывода, 254 столбец trim, 248 функции форматирования, 251 функция cols_hide(), 249 функция cols_label(), 250 функция cols_merge(), 250 функция tab_header(), 252 функция tab_spanner(), 249 правила именования, 106 пробелы, 106 руководство, 106 уникальная операция, 106 фигурные скобки, 107 Стиль программирования. См. Стиль Т Таблица стилей каскадная (CSS), 254 электронная, 166 У Указатель ресурса унифицированный (URL-адрес), 176
Предметный указатель  269 Ф Форматировщик, 109 Ш Шаблон, 137 Я Язык моделирования унифицированный (UML), 61, 132 Язык разметки веб-страницы/электронные книги/научные статьи, 123 файлы упрощенной разметки, 124 HTML, 123 LaTeX, 123 Pandoc, 125 YAML, 124 Язык разметки гипертекста (HTML), 123, 211
Книги издательства «ДМК Пресс» можно купить оптом и в розницу на складе издательства по адресу: Москва, ул. Электродная, д. 2, стр. 12, офис 7, тел. +7 (499) 322-19-38, а также заказать на сайте www.dmkpress.com с доставкой в любой регион РФ Никита Ткаченко Основы анализа данных на языке R Главный редактор Зам. главного редактора Мовчан Д. А. Яценков В. С. Перевод Корректор Верстка Дизайн обложки Логунов А. В. Синяева Г. И. Чаннова А. А. Мовчан А. Г. editor@dmkpress.com Гарнитура PT Serif. Печать цифровая. Усл. печ. л. 21,94. Тираж 200 экз. Веб-сайт издательства: www.dmkpress.com