diff --git a/book/1_introduction_to_r.qmd b/book/1_introduction_to_r.qmd
index 10ea663..6a3af48 100644
--- a/book/1_introduction_to_r.qmd
+++ b/book/1_introduction_to_r.qmd
@@ -2,7 +2,7 @@
## Установка R и RStudio
-В данной книге используется исключительно R [@r_core_team], так что для занятий понадобятся:
+В данном курсе используется исключительно R [@r_core_team], так что для занятий понадобятся:
- R
- [на Windows](https://cran.r-project.org/bin/windows/base/)
@@ -14,7 +14,7 @@ sudo apt-get install r-base
```
- RStudio --- IDE для R ([можно скачать здесь](https://www.rstudio.com/products/rstudio/download/))
-* и некоторые пакеты на R
+- и некоторые пакеты на R
Часто можно увидеть или услышать, что R --- язык программирования для "статистической обработки данных". Изначально это, конечно, было правдой, но уже давно R --- это полноценный язык программирования, который при помощи своих пакетов позволяет решать огромный спектр задач. В данной книге используется следующая версия R:
@@ -30,7 +30,7 @@ sessionInfo()$R.version$version.string |> cat()
- [Jupyter](https://jupyter.org/) ноутбуки;
- [Google Colab](https://colab.research.google.com) (нужно в настройках переключить ядро);
- [VS Code](https://code.visualstudio.com/) --- другое IDE, которое также позволяет работать с R;
-- в принципе, в IDE нет нужды, можно работать из терминала, после установки, нужно всего лишь набрать `R`.
+- в принципе, в IDE нет нужды, можно работать из терминала, после установки нужно всего лишь набрать `R`.
## Знакомство с RStudio
@@ -312,7 +312,7 @@ mean(c(1:50, NA), na.rm = TRUE)
## Датафреймы и их индексация
-Датафрейм --- это один из основных объектов в R, в котором обычно импортируют и экспортируют табличные данные. Датафрейм --- это собрание векторов одинаковой длинны. Давайте создадим датафрейм:
+Датафрейм --- это один из основных объектов в R, который обычно используется для импорта и экспорта табличных данные. Датафрейм --- это собрание векторов одинаковой длинны. Давайте создадим датафрейм:
```{r}
df <- data.frame(name = c("Анна", "Вера", "Михаил"),
@@ -363,7 +363,7 @@ iris
## Работа с пакетами
-Все богатство R находиться в его огромной инфраструктуре пакетов, которые может разрабатывать кто-угодно: от больших компаний, до частных исследователей. Чтобы их установить, нужно использовать команду `install.packages()`. Начнем с установки центрального для курса пакета: `tidyverse`:
+Все богатство R заключается в его огромной инфраструктуре пакетов, которые может разрабатывать кто угодно: от больших компаний до частных исследователей. Чтобы их установить, нужно использовать команду `install.packages()`. Начнем с установки центрального для курса пакета: `tidyverse`:
```{r}
#| eval: false
@@ -447,6 +447,6 @@ write_tsv(df, "orange_circumference_g100.tsv")
write_delim(df, "orange_circumference_g100.zsv", delim = "0")
```
-## Как справятся с проблемами
+## Как справляться с проблемами
Код не работает очень часто, очень важно внимательно читать ошибки. Если чтение не помогло, то можно скопировать ошибку в поисковик, скорее всего кто-нибудь на Stack Overflow (место, где принято задавать вопрос) или Posit Community (место для вопросов на R и Python) уже сталкивался с вашей проблемой. Кроме того, никто не может написать пакет на R, который пройдет в основной репозиторий CRAN, не задокументировав все функции пакета. В связи с этим имеет смысл искать ответы во вкладке Help в Rstudio, а также в консоли, используя знак вопроса (или два, если ничего не находится) и имя функции, например, `?write_csv` или `??read_xlsx`. wd
diff --git a/book/2_data_transformation.qmd b/book/2_data_transformation.qmd
index 1da1b2a..18e33c1 100644
--- a/book/2_data_transformation.qmd
+++ b/book/2_data_transformation.qmd
@@ -49,7 +49,7 @@ c(1:100, NA) |>
## Функции семейства `slice()`
-Дальше мы посмотрим на фрагмент данных из [исследования издания N+1](https://nplus1.ru/material/2019/06/19/greedy) дразнилки "Жадина-говядина", где исследовались социолингвистические аспекты влияющие на тенденцию к тому или иному продолжению. Переменные `word_1`, `word_2` и `word_3` соотвествуют разным вариантам начала, переменная `type` описывает классификацию, которую варианту дали исследователи, а переменная `n` отвечает за количество этих вариантов в данных.
+Дальше мы посмотрим на фрагмент данных из ["Исследования дразнилки "Жадина-говядина" издания N+1](https://nplus1.ru/material/2019/06/19/greedy), где исследовались социолингвистические аспекты влияющие на тенденцию к тому или иному продолжению. Переменные `word_1`, `word_2` и `word_3` соотвествуют разным вариантам начала, переменная `type` описывает классификацию, которую варианту дали исследователи, а переменная `n` отвечает за количество этих вариантов в данных.
```{r}
#| message: false
@@ -57,7 +57,7 @@ zhadina <- read_csv("https://raw.githubusercontent.com/agricolamz/daR4hs/main/da
zhadina
```
-Первые функции `tidyverse`, которая будет нас интересовать, --- это функции семейства `slice()`. Функция `slice()` позволяет фильтровать нужные строчки датасета по индексу:
+Первые функции `tidyverse`, которые будут нас интересовать, --- это функции семейства `slice()`. Функция `slice()` позволяет фильтровать нужные строчки датасета по индексу:
```{r}
zhadina |>
@@ -67,7 +67,7 @@ zhadina |>
slice(6:25)
```
-Стоит обратить внимание, что результат работы функции выводиться в консоль, чтобы сохранить результат работы, следует сделать операцию приписывания одним из следующих способов (первый наиболее распространенный):
+Стоит обратить внимание, что результат работы функции выводится в консоль, чтобы сохранить результат работы, следует сделать операцию приписывания одним из следующих способов (первый наиболее распространенный):
```{r}
new_zhadina <- zhadina |>
@@ -145,7 +145,7 @@ zhadina |>
## Функция `filter()`
-Функция `filter()` позволяет отфильтровыввать строки таблицы по одному или нескольким условиям.
+Функция `filter()` позволяет отфильтровывать строки таблицы по одному или нескольким условиям.
```{r}
zhadina |>
@@ -176,7 +176,7 @@ zhadina |>
filter(nchar(word_3) == 7)
```
-Кроме того, условия можно перечислить через запятую (аналог логического и):
+Кроме того, условия можно перечислить через запятую (аналог логического "и"):
```{r}
zhadina |>
@@ -216,7 +216,7 @@ zhadina |>
distinct(word_1, word_2)
```
-Функция `arrange()` позволяет отсортировать одну или несколько переменных от меньшего к большему (если нужно наоборот --- используйте функцию `desc()`). Числовые переменные соритруются по значения, а строковые по алфавиту (с учетом особенностей локали):
+Функция `arrange()` позволяет отсортировать одну или несколько переменных от меньшего к большему (если нужно наоборот --- используйте функцию `desc()`). Числовые переменные сортируются по значениям, а строковые по алфавиту (с учетом особенностей локали, см. раздел @sec-sorting):
```{r}
zhadina |>
@@ -279,7 +279,7 @@ zhadina |>
## Функция `across()`
-Функция `across()` позволяет применять одну и то же изменение к группе колонок, которые выбираются набором функций сходных с операциями для функции `select()`. Важно отметить, что трансформация обычно описывается функцией, и имя функции обычно пишут без круглых скобок.
+Функция `across()` позволяет применять одно и то же изменение к группе колонок, которые выбираются набором функций сходных с операциями для функции `select()`. Важно отметить, что трансформация обычно описывается функцией, и имя функции обычно пишут без круглых скобок.
```{r}
zhadina |>
diff --git a/book/4_working_with_strings.qmd b/book/4_working_with_strings.qmd
index e8aa9e2..fbf7ae4 100644
--- a/book/4_working_with_strings.qmd
+++ b/book/4_working_with_strings.qmd
@@ -22,7 +22,7 @@ library(tidyverse)
library(stringi)
```
-Мы будем пользоваться в основном пакетами `stingr` и `stringi`, так как они в большинстве случаях удобнее. К счастью, функции этих пакетов легко отличить от остальных: функции пакет `stringr` всегда начинаются с `str_`, а функции пакета `stringi` --- c `stri_`.
+Мы будем пользоваться в основном пакетами `stingr` и `stringi`, так как они в большинстве случаях удобнее. К счастью, функции этих пакетов легко отличить от остальных: функции пакета `stringr` всегда начинаются с `str_`, а функции пакета `stringi` --- c `stri_`.
Существует [cheat sheet по `stringr`](https://github.com/rstudio/cheatsheets/raw/master/strings.pdf).
@@ -126,7 +126,7 @@ tibble(month_name = month.name,
mutate(long_string = str_glue("The {{month}} {month_name} is abbreviated as {month_abb}"))
```
-Для разделение строки на подстроки можно использовать функцию `separate()`. Это функция разносит разделенные элементы строки в соответствующие столбцы. У функции три обязательных аргумента: `col` --- колонка, которую следует разделить, `into` --- вектор названий новых столбец, `sep` --- разделитель.
+Для разделения строки на подстроки можно использовать функцию `separate()`. Это функция разносит разделенные элементы строки в соответствующие столбцы. У функции три обязательных аргумента: `col` --- колонка, которую следует разделить, `into` --- вектор названий новых столбцов, `sep` --- разделитель.
```{r}
tibble(upper = rev(LETTERS), smaller = letters) |>
@@ -134,7 +134,7 @@ tibble(upper = rev(LETTERS), smaller = letters) |>
separate(col = merge, into = c("column_1", "column_2"), sep = "_")
```
-Кроме того, есть инструмент `str_split()`, которая позволяет разбивать строки на подстроки, но возвращает *список*.
+Кроме того, есть инструмент `str_split()`, который позволяет разбивать строки на подстроки, но возвращает *список*.
```{r}
str_split(month.name, "r")
@@ -195,7 +195,7 @@ tibble(mn = month.name) |>
mutate(mn_new = str_pad(mn, 10, pad = "."))
```
-## Сортировка
+## Сортировка {#sec-sorting}
Для сортировки существует `str_sort()`:
@@ -208,7 +208,7 @@ str_sort(unsorted_cyrillic)
str_sort(unsorted_cyrillic, locale = "ru_UA")
```
-Список локалей на копмьютере можно посмотреть командой `stringi::stri_locale_list()`. Список всех локалей вообще приведен [на этой странице](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). Еще полезные команды: `stringi::stri_locale_info` и `stringi::stri_locale_set`.
+Список локалей на компьютере можно посмотреть командой `stringi::stri_locale_list()`. Список всех локалей вообще приведен [на этой странице](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). Еще полезные команды: `stringi::stri_locale_info` и `stringi::stri_locale_set`.
## Поиск подстроки
Можно использовать функцию `str_detect()`:
@@ -247,8 +247,8 @@ str_to_sentence(latin)
```
### Выделение подстроки
-Подстроку в строке можно выделить двумя способами: по индексам функцией `str_sub()`, и по подстроке функцией `str_png()`.
+Подстроку в строке можно выделить двумя способами: по индексам функцией `str_sub()`, и по подстроке функцией `str_png()`.
```{r}
tibble(mn = month.name) |>
@@ -261,7 +261,7 @@ tibble(mn = month.name) |>
mutate(mutate = str_extract(mn, "r"))
```
-По умолчанию функция `str_extract()` возвращает первое вхождение подстроки, соответствующей шаблону. Также существует функция `str_extract_all()`, которая возвращает все вхождения подстрок, соответствующих шаблону, однако возвращает объект типа список.
+По умолчанию функция `str_extract()` возвращает первое вхождение подстроки, соответствующей шаблону. Также существует функция `str_extract_all()`, которая возвращает все вхождения подстрок, соответствующих шаблону в виде объекта типа список.
```{r}
str_extract_all(month.name, "r")
@@ -277,7 +277,7 @@ tibble(mn = month.name) |>
mutate(mutate = str_replace(mn, "r", "R"))
```
-Как и другие функции `str_replace()` делает лишь одну замену, чтобы заменить все вхождения подстроки следует использовать функцию `str_replace_all()`:
+Как и другие функции, `str_replace()` делает лишь одну замену, чтобы заменить все вхождения подстроки следует использовать функцию `str_replace_all()`:
```{r}
@@ -287,7 +287,7 @@ tibble(mn = month.name) |>
### Удаление подстроки
-Для удаления подстроки на основе шаблона, используется функция `str_remove()` и `str_remove_all()`
+Для удаления подстроки на основе шаблона используется функция `str_remove()` и `str_remove_all()`
```{r}
tibble(month.name) |>
@@ -298,7 +298,7 @@ tibble(month.name) |>
### Транслитерация строк
-В пакете `stringi` сууществует достаточно много методов транслитераций строк, которые можно вывести командой `stri_trans_list()`. Вот пример использования некоторых из них:
+В пакете `stringi` существует достаточно много методов транслитераций строк, которые можно вывести командой `stri_trans_list()`. Вот пример использования некоторых из них:
```{r}
stri_trans_general("stringi", "latin-cyrillic")
@@ -314,7 +314,7 @@ stri_trans_general("stringi", "latin-armenian")
- строка, с которой работает функция
- образец (pattern)
-Дальше мы будем использовать функцию `str_view()`, которая позволяет показывать, выделенное образцом в исходной строке.
+Дальше мы будем использовать функцию `str_view()`, которая позволяет показывать выделенное образцом в исходной строке.
```{r}
str_view("Я всегда путаю с и c", "c") # я ищу латинскую c
diff --git a/book/5_working_with_texts.qmd b/book/5_working_with_texts.qmd
index f494265..e1b6732 100644
--- a/book/5_working_with_texts.qmd
+++ b/book/5_working_with_texts.qmd
@@ -5,7 +5,7 @@ editor_options:
---
# Работа с текстами
-Не существует какого-то единого алгоритма анализа текстов, многое зависит от задач. Однако все обычные сферы анализа данных применимы к текстам: иногда нужно выделить какие-то составляющие текста (частота встречаемости каких-то единиц, сентимент анализ), иногда нужно выделить уникальные единицы свойственные какой-то группе текстов (мера tf-idf), иногда нужно кластеризовать тексты, чтобы найти похожие/разные тексты (например, класическая задача определения спамерских сообщений). Такие задачи находятся на стыке лингвистики и компьютерных наук. Существуют и более сложные/интеллектуальные задачи, которые традиционно относят к области исскуственного интеллекта, такие как перевод с одного языка на другой, саммаризация текста, вопросно-ответные системы и другие. В данном разделе мы коснемся лишь первой группы задач и пакеты, написанные на R для их решения.
+Не существует какого-то единого алгоритма анализа текстов, многое зависит от задач. Однако все обычные сферы анализа данных применимы к текстам: иногда нужно выделить какие-то составляющие текста (частота встречаемости каких-то единиц, сентимент анализ), иногда нужно выделить уникальные единицы свойственные какой-то группе текстов (мера tf-idf), иногда нужно кластеризовать тексты, чтобы найти похожие/разные тексты (например, класическая задача определения спамерских сообщений). Такие задачи находятся на стыке лингвистики и компьютерных наук. Существуют и более сложные/интеллектуальные задачи, которые традиционно относят к области исскуственного интеллекта, такие как перевод с одного языка на другой, саммаризация текста, вопросно-ответные системы и другие. В данном разделе мы коснемся лишь первой группы задач и пакетов, написанных на R для их решения.
## Загрузка текстов в R {#sec-encoding}
@@ -28,7 +28,7 @@ read_lines("https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w5_the
n_max = 15)
```
-В функциях пакета `readr` (т. е. не только `read_lines()`, но и в функциях `read_csv()`, `read_tsv()` и т. п.) есть аргумент `locale`, который позволяет эксплицитно указать кодировку, а при считывании происходит процесс конвертации в стандартный для многих операционных систем `UTF-8`. Для текстов на русском языке важны следующие кодировки
+В функциях пакета `readr` (т. е. не только в функции `read_lines()`, но и в функциях `read_csv()`, `read_tsv()` и т. п.) есть аргумент `locale`, который позволяет эксплицитно указать кодировку, а при считывании происходит процесс конвертации в стандартный для многих операционных систем `UTF-8`. Для текстов на русском языке важны следующие кодировки
- `KOI8-R`, а для украинского языка --- `KOI8-U`;
- `CP1251` (также известная под названием `Windows-1251`) покрывает и другие кириллические письменности такие как украинский, белорусский, болгарский, сербский, македонский и другие.
@@ -78,7 +78,7 @@ x
library(gutenbergr)
```
-Все самое важное в пакете хранится во встроенном датасете `gutenberg_metadata` --- аналоге:
+Все самое важное в пакете хранится во встроенном датасете `gutenberg_metadata`:
```{r}
str(gutenberg_metadata)
@@ -126,7 +126,7 @@ books |>
count(title)
```
-Обратите на аргумент `meta_fields`, который позволяет кроме самого текста добавить метаданные из `gutenberg_metadata` в получившийся датафрейм.
+Обратите внимание на аргумент `meta_fields`, который позволяет кроме самого текста добавить метаданные из `gutenberg_metadata` в получившийся датафрейм.
### Пакет `rperseus`
@@ -146,20 +146,20 @@ remotes::install_github("ropensci/rperseus")
library(rperseus)
```
-Библиотечный каталог пакета `rperseus` находиться в переменной `perseus_catalog`:
+Библиотечный каталог пакета `rperseus` находится в переменной `perseus_catalog`:
```{r}
str(perseus_catalog)
```
-На каких языках содержаться тексты?
+На каких языках содержатся тексты?
```{r}
perseus_catalog |>
count(language)
```
-А документации объясняется:
+В документации объясняется:
- `grc` --- греческий;
- `lat` --- латинский;
@@ -186,7 +186,7 @@ augustins_confession
get_perseus_text("urn:cts:latinLit:stoa0040.stoa001.opp-lat1", excerpt = 4)
```
-К сожалению, пакет не позволяет скачивать много текстов за раз, но в документации описано как это можно сделать при помощи цикла. Кому-то может показаться полезной функция `perseus_parallel()`, которая позволяет видеть параллельные фрагменты текста. Проиллюстрируем это на примере Эвменид Эсхила:
+К сожалению, пакет не позволяет скачивать много текстов за раз, но в документации описано, как это можно сделать при помощи цикла. Кому-то может показаться полезной функция `perseus_parallel()`, которая позволяет видеть параллельные фрагменты текста. Проиллюстрируем это на примере Эвменид Эсхила:
```{r eumenides}
#| cache: true
@@ -207,7 +207,7 @@ aeschylus_eumenides_eng |>
### Библиотека lib.ru
-Для текстов на русском языке отдельного пакета не написали, однако на сайте библиотеки [lib.ru](lib.ru) они уже представлены в машиночитаемом виде, нужно всего лишь выбрать вариант отображение txt, полученную ссылку считать в R, указав корректную кодировку (см. @sec-encoding):
+Для текстов на русском языке отдельного пакета не написали, однако на сайте библиотеки [lib.ru](lib.ru) они уже представлены в машиночитаемом виде, нужно всего лишь выбрать вариант отображения `txt`, полученную ссылку считать в R, указав корректную кодировку (см. @sec-encoding):
```{r}
read_lines("http://lib.ru/LITRA/PUSHKIN/kapitan.txt_Ascii.txt",
@@ -221,7 +221,6 @@ read_lines("http://lib.ru/LITRA/PUSHKIN/kapitan.txt_Ascii.txt",
Сейчас скачанные тексты записывались в таблицу, где одна строка содержала один абзац. Однако для анализа текста нужно уметь работать с отдельными словами в нем. Для этого тексты нужно привести в tidy формат. С этим отлично справляется пакет `tidytext` (онлайн книга доступна [здесь](https://www.tidytextmining.com/)). Основное "оружие" пакета `tidytext` функция `unnest_tokens()`, которая переводит текст в tidy формат. В аргумент `output` подается вектор с именем будущей переменной, а аргумент `input` принимает переменную с текстом.
-
```{r}
library(tidytext)
alices_adventures_in_wonderland |>
@@ -229,7 +228,7 @@ alices_adventures_in_wonderland |>
unnest_tokens(output = "word", input = text)
```
-По умолчанию функция `unnest_tokens()` удаляет знаки препинания и приводит слова к нижнему регистру. Давайте для удобства удалим все вплоть до оглавления и создадим датафрейм, в которых будет понятно, где какая глава книги:
+По умолчанию функция `unnest_tokens()` удаляет знаки препинания и приводит слова к нижнему регистру. Давайте для удобства удалим все вплоть до оглавления и создадим датафрейм и переменную, из которой будет понятно, где какая глава книги:
```{r}
alices_adventures_in_wonderland |>
@@ -248,7 +247,7 @@ alices_adventures_in_wonderland |>
alice_cleaned
```
-В приведенном выше коде интерес представляет функция `fill()`, которая заполнила пропущенные значения `NA` значениями выше. В остальном мы использовали не сложные регулярные выражения из @sec-regex. Кроме того мы воспользовались встроенными функциями `as.roman()` и `as.numeric()`, чтобы преобразовать римские номера глав в арабские. Теперь мы готовы анализировать частотность слов. Создадим переменную `tidy_alice` и посчитаем слова в каждой из глав:
+В приведенном выше коде интерес представляет функция `fill()`, которая заполнила пропущенные значения `NA` значениями выше. В остальном мы использовали несложные регулярные выражения из @sec-regex. Кроме того, мы воспользовались встроенными функциями `as.roman()` и `as.numeric()`, чтобы преобразовать римские номера глав в арабские. Теперь мы готовы анализировать частотность слов. Создадим переменную `tidy_alice` и посчитаем слова в каждой из глав:
```{r}
alice_cleaned |>
@@ -272,7 +271,7 @@ tidy_alice |>
labs(x = NULL, y = NULL)
```
-Хорошие знатоки "Алисы в Зазеркалье", конечно многое понимают из распределения местоимений *you* и, наверное, догадываются, почему это слово становиться первым, однако в большинстве случаев служебные слова неинформативны при анализе текстов. Для этого для некоторых языков составили списки стоп-слов --- служебных слов, которые никак не приближают к пониманию текста. Отдельный список уже встроен в пакет `tidytext` в переменную `stop_words` (см. также следующий раздел):
+Хорошие знатоки "Алисы в Зазеркалье", конечно, многое понимают из распределения местоимений *you* и, наверное, догадываются, почему это слово становится первым, однако в большинстве случаев служебные слова неинформативны при анализе текстов. Поэтому для некоторых языков составили списки стоп-слов --- служебных слов, которые никак не приближают к пониманию текста. Отдельный список уже встроен в пакет `tidytext` в переменную `stop_words` (см. также следующий раздел):
```{r}
stop_words
@@ -292,7 +291,7 @@ tidy_alice |>
labs(x = NULL, y = NULL)
```
-Получившийся результат уже значительно интереснее, однако алфавитный порядок слов в каждом фасете немного мешает. Для того, чтобы победить это в пакете `tidytext` есть нескольок функций:
+Получившийся результат уже значительно интереснее, однако алфавитный порядок слов в каждом фасете немного мешает. Для того, чтобы победить это, в пакете `tidytext` есть несколько функций:
- `reorder_within()` --- функция которая позволяет указать группировку, внутри которой нужно упорядочить единицы;
- `scale_y_reordered()`/`scale_x_reordered()` --- функция, которая маскирует работу `reorder_within()` при отображении на графике.
@@ -341,7 +340,7 @@ alice_cleaned |>
## Пакет `stopwords`
-Выше мы упомянули, что в пакет `tidytext` встроен список английских стопслов. Стопслова для других язков можно раздобыть списки для других языков, используя пакет `stopwords`. Вместо имени языка, функция принимает ISO код языыка:
+Выше мы упомянули, что в пакет `tidytext` встроен список английских стоп-слов. Стоп-слова для других язков можно раздобыть списки для других языков, используя пакет `stopwords`. Вместо имени языка, функция принимает ISO код языыка:
```{r}
library(stopwords)
@@ -369,7 +368,7 @@ length(stopwords("ru", source = "marimo"))
length(stopwords("ru", source = "nltk"))
```
-В результате мы можем сделать анализ аналогичный анализу Алисы из прошлого раздела для русского текста:
+В результате мы можем сделать анализ, аналогичный анализу Алисы из прошлого раздела, для текста на русском языке:
```{r}
captains_daughter <- read_lines("https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w5_the_captains_daughter_koi8r.txt",
@@ -419,7 +418,7 @@ udpipe("Жила-была на свете крыса в морском порт
object = rumodel)
```
-После того как модель скачана можно к ней обращаться просто по имени файла:
+После того, как модель скачана, можно к ней обращаться просто по имени файла:
```{r}
udpipe("Жила-была на свете крыса в морском порту Вальпараисо, на складе мяса и маиса, какао и вина.",
@@ -450,7 +449,7 @@ abstracts_dataset |>
model
```
-Получившиеся эмбединги можно получить
+Эмбединги из переменной `model` можно получить следующим образом:
```{r}
as.matrix(model, which = "docs") |>
@@ -470,4 +469,4 @@ as.matrix(model, which = "docs") |>
stat_ellipse()
```
-Мы видим, что у аннотаций есть что-то общее, но в общем, аннотации распадаются на три группы. Важно, что расцветка у нас уже была в датасете и алгоритм векторизации ее не видел, так что получившееся пространство отражает карту анализируемых текстов. Стоит отметить, что качесвто получишвегося пространства напрямую зависит от объема данных.
+Мы видим, что у аннотаций есть что-то общее, но, в общем, аннотации распадаются на три группы. Важно, что расцветка у нас уже была в датасете и алгоритм векторизации ее не видел, так что получившееся пространство отражает карту анализируемых текстов. Стоит отметить, что качество получившегося пространства напрямую зависит от объема данных.
diff --git a/book/5_working_with_texts_files/figure-html/unnamed-chunk-39-1.png b/book/5_working_with_texts_files/figure-html/unnamed-chunk-39-1.png
index 034c2ca..aa8b752 100644
Binary files a/book/5_working_with_texts_files/figure-html/unnamed-chunk-39-1.png and b/book/5_working_with_texts_files/figure-html/unnamed-chunk-39-1.png differ
diff --git a/book/6_working_with_time.qmd b/book/6_working_with_time.qmd
index 1a9054d..4bf3a62 100644
--- a/book/6_working_with_time.qmd
+++ b/book/6_working_with_time.qmd
@@ -53,7 +53,7 @@ today()
now()
```
-Как видно, из этих функций в R можно работать как с датами, так и со временем. В качестве иллюстрации мы будем использовать датасет `flights` из пакета `nycflights13`, в котором содержатся данные полетов из Нью Йорка в 2013 года.
+Как видно из этих функций в R можно работать как с датами, так и со временем. В качестве иллюстрации мы будем использовать датасет `flights` из пакета `nycflights13`, в котором содержатся данные полетов из Нью Йорка в 2013 году.
```{r}
library(nycflights13)
@@ -104,7 +104,7 @@ flights |>
## Работа с часовыми поясами
-Земля разбита на условные географическо-административные зоны, в которых действуют свои правила работы со временем. В каких-то зонах есть переход на зимнее/летнее время, а где-то его нет. В некоторых точках Земли понятие часового пояса не имеет смысла, однако все равно есть конвенции того, какое время на этой теретории использовать. Функция `make_datetime()`, которую мы рассмотрели, использует по-умолчанию всемирное координированное время (UTC). Обозначение интересующего часового пояса можно посмотреть в интернете, однако основная информации о возможных значениях аргумента `tz` хранится в системе пользователя.
+Земля разбита на условные географическо-административные зоны, в которых действуют свои правила работы со временем. В каких-то зонах есть переход на зимнее/летнее время, а где-то его нет. В некоторых точках Земли понятие часового пояса не имеет смысла, однако все равно есть конвенции того, какое время на этой территории использовать. Функция `make_datetime()`, которую мы рассмотрели, использует по-умолчанию всемирное координированное время (UTC). Обозначение интересующего часового пояса можно посмотреть в интернете, однако основная информации о возможных значениях аргумента `tz` хранится в системе пользователя.
```{r}
dmy_hm("21-01-2001 15^43", tz = "Europe/Moscow")
@@ -142,7 +142,7 @@ minute(date_example)
second(date_example)
```
-Так же есть функция `leap_year()`, которая сообщает информацию, является ли выбранный год високосным:
+Также есть функция `leap_year()`, которая сообщает, является ли выбранный год високосным:
```{r}
leap_year(2019)
@@ -159,11 +159,13 @@ ymd("2020-01-19") - ymd("2020-01-21")
```
Обратите внимание на результат работы этого выражения:
+
```{r, message=FALSE}
hm("21:00") - hm("18:10")
```
-Видимо, почему-то в таком использовании происходит поэлементная операция с часами, минутами, и секундами, так что в результате получаются отрицательные минуты. Однако, если использовать полные даты, то этого эффекта нет:
+Видимо, почему-то при таком использовании происходит поэлементная операция с часами, минутами, и секундами, так что в результате получаются отрицательные минуты. Однако, если использовать полные даты, то этого эффекта нет:
+
```{r}
ymd_hm("2020-01-21, 21:00") - ymd_hm("2020-01-21, 18:10")
ymd_hm("2020-01-21, 21:00") - hm("18:10")
@@ -176,10 +178,10 @@ difftime(ymd_hm("2020-01-21, 21:00"), ymd_hm("2020-01-21, 18:10"), units = "mins
difftime(ymd_hm("2020-01-21, 21:00"), ymd_hm("2020-01-21, 18:10"), units = "hours")
```
-Однако простые даты, не являются временными отрезками, так что их нельзя складывать, вычитать, умножать и т. д. Для удобства операций в `lubridate` вводится несколько сущностей:
+Однако простые даты не являются временными отрезками, так что их нельзя складывать, вычитать, умножать и т. д. Для удобства операций в `lubridate` вводится несколько сущностей:
-* **periods** --- промежутки времени, которые игнорируют нерегулярности во времени, сразу прибавляя 1 к соответствующему разряду, вводятся функциями `years()`, `months()`, `weeks()`, `days()`, `hours()`, `minutes()`, `seconds()`, `period()`
-* **duration** --- промежутки времени, которые учитывают нерегулярности во времени, добавляя стандартную длительность единицы, вводятся функциями `dyears()`, `dweeks()`, `ddays()`, `dhours()`, `dminutes()`, `dseconds()`, `duration()`
+- **periods** --- промежутки времени, которые игнорируют нерегулярности во времени, сразу прибавляя 1 к соответствующему разряду, вводятся функциями `years()`, `months()`, `weeks()`, `days()`, `hours()`, `minutes()`, `seconds()`, `period()`
+- **duration** --- промежутки времени, которые учитывают нерегулярности во времени, добавляя стандартную длительность единицы, вводятся функциями `dyears()`, `dweeks()`, `ddays()`, `dhours()`, `dminutes()`, `dseconds()`, `duration()`
![](images/06_periods-durations.png)
@@ -245,14 +247,15 @@ unwelcomed |>
labs(y = "number of death/missing")
```
-Однако ко переменным со врменем не всегда относятся аккуратно. Рассмотрим график с сайта Левада-центра --- российской негосударственной исследовательской организации, которая проводит социологические и маркетинговые исследования (график взят [отсюда](https://www.levada.ru/indikatory/otnoshenie-k-stranam/)):
+Однако к переменным со временем не всегда относятся аккуратно. Рассмотрим график с сайта Левада-центра --- российской негосударственной исследовательской организации, которая проводит социологические и маркетинговые исследования (график взят [отсюда](https://www.levada.ru/indikatory/otnoshenie-k-stranam/)):
-![](images/11-levada.png)
+![](images/06_levada.png)
-На первый взгляд, в этом графике нет ничего странного, однако если присмотреться к динамической версии на сайте Левада-центра, можно обнаружить, что на идущие подряд измерения расположены на одинаковом расстоянии друг от друга, например, 05.2014, 07.2014, 11.2014. Вот [здесь](https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w6_2019.01_levada_countries.csv) можно скачать данные, по которым строился этот график. Вот как он выглядит, если считать временную переменную как время
+На первый взгляд, в этом графике нет ничего странного, однако если присмотреться к динамической версии на сайте Левада-центра, можно обнаружить, что не идущие подряд значения расположены на одинаковом расстоянии друг от друга, например, 05.2014, 07.2014, 11.2014. Вот [здесь](https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w6_2019.01_levada_countries.csv) можно скачать данные, по которым строился этот график. Вот как он выглядит, если считать временную переменную как время
```{r, warning=FALSE,message=FALSE}
levada <- read_csv("https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w6_2019.01_levada_countries.csv")
+
levada |>
mutate(date = str_c("1-", date),
date = dmy(date)) |>
diff --git a/book/7_working_with_geodata.qmd b/book/7_working_with_geodata.qmd
index 9b43e9a..1a87170 100644
--- a/book/7_working_with_geodata.qmd
+++ b/book/7_working_with_geodata.qmd
@@ -7,12 +7,12 @@ editor_options:
## Векторная и растровая графика
-Перед тем как обсуждать карты, следует сначала обсудить разницу между векторной и растровой графикой.
+Перед тем, как обсуждать карты, следует сначала обсудить разницу между векторной и растровой графикой.
-- **Растровые изображения** представляют собой набор упорядоченных пикселей, про каждый из которых храниться информация о цвете. Векторное изображение нельзя бесконечно увеличивать --- в какой-то момент станут видны пиксели, которые в каком-то смысле являются пределом увелечения. Наиболее популярные форматы растровых изображений: `JPEG`, `GIF`, `PNG`, `BMP`, `TIFF` и другие.
-- В **векторных изображениях** инормация храниться как собрани точек, линий и полигонов в некоторой системе координат, что позволяет бесконечно увеличивать такие изображения не теряя в качестве. Наиболее популярные форматы векторных изображений: `PDF`, `SVG`, `EPS` и другие.
+- **Растровые изображения** представляют собой набор упорядоченных пикселей, про каждый из которых хранится информация о цвете. Векторное изображение нельзя бесконечно увеличивать --- в какой-то момент станут видны пиксели, которые в каком-то смысле являются пределом увеличения. Наиболее популярные форматы растровых изображений: `JPEG`, `GIF`, `PNG`, `BMP`, `TIFF` и другие.
+- В **векторных изображениях** информация хранится как собрание точек, линий и полигонов в некоторой системе координат, что позволяет бесконечно увеличивать такие изображения не теряя в качестве. Наиболее популярные форматы векторных изображений: `PDF`, `SVG`, `EPS` и другие.
-Современные технологии позволяют соединять растровые и векторные изображения, а также трансформировать их друг в друга. Картографические данные могут попадать в разные типы: точки (столицы всех стран), линии (улицы в каком-нибудь городе), полигоны (границы стран и меньших регионов) обычно имеют некоторую геопривязку (для простоты давайте считать такими, все, что имеет широту и долготу), так что могут быть представлены векторно, однако существует достаточно много информации, которую невозможно представить никак подругому, кроме как векторно: спутниковые снимки, существующие физические/политические/климатические/исторические и т. п. карты, выдача картографических сервисов, таких как Google Maps. Кроме того, занимаясь любыми типами визуализации следует помнить о разнице **статической визаулизации**, которую после создания нельзя изменить, и **динамической визуализации**, которая позволяет пользователям изменять себя (увеличиваться и уменьшаться, кликать на собрание точек и видеть их значения и т. п.). В данной главе, в отличие от предыдущих мы сосредоточимся на пакете для динамичского картографирования `leaflet`. Достаточно много тем останется за пределами этой главы: изменение проекции, манипуляции с географическими данными, работа с растровыми изображениями и другие (см., например, [@lovelace2019], доступная [он-лайн](https://geocompr.robinlovelace.net/)).
+Современные технологии позволяют соединять растровые и векторные изображения, а также трансформировать их друг в друга. Картографические данные могут попадать в разные типы: точки (столицы всех стран), линии (улицы в каком-нибудь городе), полигоны (границы стран и меньших регионов) обычно имеют некоторую геопривязку (для простоты давайте считать таким все, что имеет широту и долготу), так что могут быть представлены векторно, однако существует достаточно много информации, которую невозможно представить никак по-другому, кроме как векторно: спутниковые снимки, существующие физические/политические/климатические/исторические и т. п. карты, выдача картографических сервисов, таких как Google Maps. Кроме того, занимаясь любыми типами визуализации следует помнить о разнице **статической визуализации**, которую после создания нельзя изменить, и **динамической визуализации**, которая позволяет пользователям изменять себя (увеличивать и уменьшать, кликать на собрание точек и видеть их значения и т. п.). В данной главе, в отличие от предыдущих, мы сосредоточимся на пакете для динамического картографирования `leaflet`. Достаточно много тем останется за пределами этой главы: изменение проекции, манипуляции с географическими данными, работа с растровыми изображениями и другие (см., например, [@lovelace2019], доступная [он-лайн](https://geocompr.robinlovelace.net/)).
## Картографические примитивы
@@ -29,7 +29,7 @@ knitr::include_graphics("images/07_geographical_classes.png")
## Пакет leaflet
-Мы пойдем необычным путем и начнем с инструмента, который создает динамические карты --- пакета `leaflet`, который является оберткой для одноименного популярного пакета для визаулизации карт в интернете на JS.
+Мы пойдем необычным путем и начнем с инструмента, который создает динамические карты --- пакета `leaflet`, который является оберткой для одноименного популярного пакета для визуализации карт в интернете на JS.
Для начала включим библиотеки:
@@ -44,7 +44,7 @@ library("tidyverse")
### `.csv` файлы
-Источником географических данных могут быть обычные привычные нам csv файлы. Например, вот [здесь](https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w6_death_of_migrants_and_refugees_from_the_Unwelcomed_project.csv), хранится датасет из проекта [The Unwelcomed](http://alhadaqa.com/2019/08/the_unwelcomed/) Мохамада А. Вэйкда (Mohamad A. Waked), содержащий информацию о месте и причинах смерти мигрантов и беженцев по всему миру с января 2014 года по июнь 2019 года.
+Источником географических данных могут быть обычные привычные нам csv файлы. Например, вот [здесь](https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w6_death_of_migrants_and_refugees_from_the_Unwelcomed_project.csv) хранится датасет из проекта [The Unwelcomed](http://alhadaqa.com/2019/08/the_unwelcomed/) Мохамада А. Вэйкда (Mohamad A. Waked), содержащий информацию о месте и причинах смерти мигрантов и беженцев по всему миру с января 2014 года по июнь 2019 года.
```{r}
#| message: false
@@ -76,7 +76,7 @@ unwelcomed |>
### Формат `.geojson`
-Существует несколько форматов, в которых принято распространять картографические данные, и если точки удобно хранить в `.csv` формате, то с полигонами и линиями `tidy` подход одно наблюдение -- одна строчка не подходит. Наиболее распространненые являюся `.geojson` и `.shp`. Формат `.geojson` можно прочитать при помощи функции `read_json()` из пакета `jsonlite` (я вызываю эту функцию, не загружая пакета, так как пакет `jsonlite` конфликтует с `tidyverse`):
+Существует несколько форматов, в которых принято распространять картографические данные, и если точки удобно хранить в `.csv` формате, то с полигонами и линиями `tidy` подход одно наблюдение -- одна строчка не подходит. Наиболее распространенными являются `.geojson` и `.shp`. Формат `.geojson` можно прочитать при помощи функции `read_json()` из пакета `jsonlite` (я вызываю эту функцию, не загружая пакета, так как пакет `jsonlite` конфликтует с `tidyverse`):
```{r}
moscow_districts <- jsonlite::read_json("https://raw.githubusercontent.com/agricolamz/daR4hs/main/data/w7_moscow.geojson")
@@ -109,7 +109,7 @@ unwelcomed |>
lat = ~lat)
```
-Функция `addCircles()` имеет массу аргументов, которая отвечает за отображение:
+Функция `addCircles()` имеет массу аргументов, которые отвечают за отображение:
* `radius`
* `color`
@@ -171,7 +171,7 @@ unwelcomed |>
### Комбинация карт: `leafsync`
-Карты, как и все объекты в R тоже можно записать в переменную:
+Карты, как и все объекты в R, тоже можно записать в переменную:
```{r}
unwelcomed |>
@@ -190,7 +190,7 @@ unwelcomed |>
m_2014
```
-Теперь если вызвать переменную `m_2014`, появится карта, которую мы сделали. Но, что если мы хотим отобразить рядом карты 2014 года и 2015 года? Как сделать фасетизацию? К сожалению, функции для фасетизации в пакете не предусмотрена, но мы можем сделать ее самостоятельно. Для начала создадим вторую карту:
+Теперь, если вызвать переменную `m_2014`, появится карта, которую мы сделали. Но что, если мы хотим отобразить рядом карты 2014 года и 2015 года? Как сделать фасетизацию? К сожалению, функции для фасетизации в пакете не предусмотрено, но мы можем сделать ее самостоятельно. Для начала создадим вторую карту:
```{r}
unwelcomed |>
@@ -215,7 +215,7 @@ unwelcomed |>
library(leafsync)
```
-И теперь соединим две карты воедино:
+И теперь соединим две карты:
```{r}
sync(m_2014, m_2015)
diff --git a/book/index.qmd b/book/index.qmd
index 42082e2..d8e4433 100644
--- a/book/index.qmd
+++ b/book/index.qmd
@@ -1,3 +1,3 @@
# Введение {.unnumbered}
-Данные материалы являются конспектом онлайн курса Г. А. Мороз ‘Введение в анализ данных на R для гуманитарных и социальных наук’
\ No newline at end of file
+Данные материалы являются конспектом онлайн курса Г. А. Мороза ‘Введение в анализ данных на R для гуманитарных и социальных наук’
\ No newline at end of file
diff --git a/docs/1_introduction_to_r.html b/docs/1_introduction_to_r.html
index fdf8c22..d5e6532 100644
--- a/docs/1_introduction_to_r.html
+++ b/docs/1_introduction_to_r.html
@@ -250,7 +250,7 @@
В данной книге используется исключительно R (R Core Team 2023), так что для занятий понадобятся:
+
В данном курсе используется исключительно R (R Core Team 2023), так что для занятий понадобятся:
R
@@ -305,7 +305,7 @@
Jupyter ноутбуки;
Google Colab (нужно в настройках переключить ядро);
VS Code — другое IDE, которое также позволяет работать с R;
-
в принципе, в IDE нет нужды, можно работать из терминала, после установки, нужно всего лишь набрать R.
+
в принципе, в IDE нет нужды, можно работать из терминала, после установки нужно всего лишь набрать R.
@@ -746,7 +746,7 @@
1.9 Датафреймы и их индексация
-
Датафрейм — это один из основных объектов в R, в котором обычно импортируют и экспортируют табличные данные. Датафрейм — это собрание векторов одинаковой длинны. Давайте создадим датафрейм:
+
Датафрейм — это один из основных объектов в R, который обычно используется для импорта и экспорта табличных данные. Датафрейм — это собрание векторов одинаковой длинны. Давайте создадим датафрейм:
Все богатство R находиться в его огромной инфраструктуре пакетов, которые может разрабатывать кто-угодно: от больших компаний, до частных исследователей. Чтобы их установить, нужно использовать команду install.packages(). Начнем с установки центрального для курса пакета: tidyverse:
+
Все богатство R заключается в его огромной инфраструктуре пакетов, которые может разрабатывать кто угодно: от больших компаний до частных исследователей. Чтобы их установить, нужно использовать команду install.packages(). Начнем с установки центрального для курса пакета: tidyverse:
Код не работает очень часто, очень важно внимательно читать ошибки. Если чтение не помогло, то можно скопировать ошибку в поисковик, скорее всего кто-нибудь на Stack Overflow (место, где принято задавать вопрос) или Posit Community (место для вопросов на R и Python) уже сталкивался с вашей проблемой. Кроме того, никто не может написать пакет на R, который пройдет в основной репозиторий CRAN, не задокументировав все функции пакета. В связи с этим имеет смысл искать ответы во вкладке Help в Rstudio, а также в консоли, используя знак вопроса (или два, если ничего не находится) и имя функции, например, ?write_csv или ??read_xlsx. wd
Дальше мы посмотрим на фрагмент данных из исследования издания N+1 дразнилки “Жадина-говядина”, где исследовались социолингвистические аспекты влияющие на тенденцию к тому или иному продолжению. Переменные word_1, word_2 и word_3 соотвествуют разным вариантам начала, переменная type описывает классификацию, которую варианту дали исследователи, а переменная n отвечает за количество этих вариантов в данных.
+
Дальше мы посмотрим на фрагмент данных из “Исследования дразнилки”Жадина-говядина” издания N+1, где исследовались социолингвистические аспекты влияющие на тенденцию к тому или иному продолжению. Переменные word_1, word_2 и word_3 соотвествуют разным вариантам начала, переменная type описывает классификацию, которую варианту дали исследователи, а переменная n отвечает за количество этих вариантов в данных.
+ word_1 word_2 word_3 type n
+ <chr> <chr> <chr> <chr> <dbl>
+1 жадина-говядина гнилая шоколадина шоколадина 12
+2 жадина-говядина сухая шоколадина шоколадина 16
+3 жадина-говядина соленый помидор другое 17
+4 жадина-говядина кусок шоколадины шоколадина 113
+5 жадина-говядина булка шоколадина шоколадина 250
+6 жадина-говядина никто ее не ест другое 10
+7 жадина-говядина немецкий барабан барабан 12
@@ -599,7 +599,7 @@
2.5 Функция filter()
-
Функция filter() позволяет отфильтровыввать строки таблицы по одному или нескольким условиям.
+
Функция filter() позволяет отфильтровывать строки таблицы по одному или нескольким условиям.
zhadina |>filter(n >100)
@@ -764,7 +764,7 @@
-
Кроме того, условия можно перечислить через запятую (аналог логического и):
+
Кроме того, условия можно перечислить через запятую (аналог логического “и”):
zhadina |>filter(n >15,
@@ -904,7 +904,7 @@
Раздел 4.5):
zhadina |>count(word_3) |>
@@ -1116,7 +1116,7 @@
2.9 Функция across()
-
Функция across() позволяет применять одну и то же изменение к группе колонок, которые выбираются набором функций сходных с операциями для функции select(). Важно отметить, что трансформация обычно описывается функцией, и имя функции обычно пишут без круглых скобок.
+
Функция across() позволяет применять одно и то же изменение к группе колонок, которые выбираются набором функций сходных с операциями для функции select(). Важно отметить, что трансформация обычно описывается функцией, и имя функции обычно пишут без круглых скобок.