Please open Telegram to view this post
VIEW IN TELEGRAM
Округление в R
Вчера мы столкнулись с расхождением в расчёте LT на одних и тех же данных в Power BI и R. После некоторого ресёрча я понял, что разница была в округлении. Функция
Впервые для себя я узнал, что функция
Банковское округление:
● Числа с десятичной частью .5 округляются до ближайшего чётного целого числа.
● Например, 2.5 округляется до 2, а 3.5 округляется до 4.
Математическое округление:
● Числа с десятичной частью .5 всегда округляются вверх.
● Например, 2.5 округляется до 3, а 3.5 тоже округляется до 4.
То есть если вы через
Как оказалось, в базовом R вообще нет функции для математического округления. Поэтому если вдруг вам понадобится где-то использовать математическое округление, которое мы с вами учили в школе, придётся писать собственную функцию. Ниже приведена функция, которая математическим способом округляет дробные числа до целого:
Если вы хотите иметь возможность указать количество разрядов после запятой, то используйте эту функцию:
#заметки_по_R
Вчера мы столкнулись с расхождением в расчёте LT на одних и тех же данных в Power BI и R. После некоторого ресёрча я понял, что разница была в округлении. Функция
round()
в R округлила число 6.5 до 6, а Power BI - до 7.Впервые для себя я узнал, что функция
round()
использует не привычный нам математический способ округления, а так называемый банковский. Вот в чём их отличия:Банковское округление:
● Числа с десятичной частью .5 округляются до ближайшего чётного целого числа.
● Например, 2.5 округляется до 2, а 3.5 округляется до 4.
Математическое округление:
● Числа с десятичной частью .5 всегда округляются вверх.
● Например, 2.5 округляется до 3, а 3.5 тоже округляется до 4.
То есть если вы через
round()
попробуете округлить числа 2.5, 4.5, 6.5, то получите соответственно 2, 4, 6, а не ожидаемые 3, 5, 7.Как оказалось, в базовом R вообще нет функции для математического округления. Поэтому если вдруг вам понадобится где-то использовать математическое округление, которое мы с вами учили в школе, придётся писать собственную функцию. Ниже приведена функция, которая математическим способом округляет дробные числа до целого:
round_math <- function(x) {
sign(x) * floor(abs(x) + 0.5)
}
Если вы хотите иметь возможность указать количество разрядов после запятой, то используйте эту функцию:
custom_round <- function(x, digits = 0) {
posneg <- sign(x) # Определяем знак числа
z <- abs(x) * 10^digits
z <- z + 0.5 # Добавляем 0.5 для округления вверх
z <- floor(z)
return(posneg * z / 10^digits)
}
#заметки_по_R
Динамическая вставка таблиц в RMarkdown
Допустим у вас есть большой дата фрейм, в котором есть один, или несколько столбцов, позволяющий разбить данные на какие то категории по отдельным таблицам, например по отделу, региону, или другому признаку. Далее в RMarkdown вам необходимо каждую подтаблицу напечатать отдельно, при этом количество этих категорий может меняться, ниже я покажу один из способов сделать это.
Изначально вам необходимо с помощью функции
Теперь для того, что бы каждую подтаблицу вывести в RMarkdown как отдельную таблицу необходимо пройтись по списку подтаблиц, например с помощью функции
Ниже небольшой пример кода, как это можно сделать:
Этот код делает следующее:
1. Разбивает таблицу
2. Использует
3. Создает HTML-таблицу для каждой подтаблицы с помощью
4. Добавляет стили с
5. Выводит каждую таблицу в документ с помощью
6. Добавляет пустые строки между таблицами для лучшей читаемости.
Надеюсь, этот подход будет полезен в вашей работе с RMarkdown. Если у вас возникнут вопросы или вы захотите поделиться своими методами работы с данными, пишите в комментариях!
#заметки_по_R
Допустим у вас есть большой дата фрейм, в котором есть один, или несколько столбцов, позволяющий разбить данные на какие то категории по отдельным таблицам, например по отделу, региону, или другому признаку. Далее в RMarkdown вам необходимо каждую подтаблицу напечатать отдельно, при этом количество этих категорий может меняться, ниже я покажу один из способов сделать это.
Изначально вам необходимо с помощью функции
split()
разбить основную таблицу, на подтаблицы, о том как это сделать я уже рассказывал. Теперь для того, что бы каждую подтаблицу вывести в RMarkdown как отдельную таблицу необходимо пройтись по списку подтаблиц, например с помощью функции
purrr:walk()
, и вывести по очереди их на печать. Ниже небольшой пример кода, как это можно сделать:
library(knitr)
library(kableExtra)
library(purrr)
# разбиваем большую таблицу на список подтаблиц
df_list <- split(df, df$type)
# печатаем по очереди каждую из подтаблиц
purrr::walk(names(df_list), ~{
cat(
knitr::kable(df_list[[.x]], caption = paste("Таблица для типа:", .x), format = "html") %>%
kableExtra::kable_styling(full_width = FALSE) %>%
as.character()
)
cat("\n\n") # Добавляем пустые строки между таблицами
})
Этот код делает следующее:
1. Разбивает таблицу
df
на список подтаблиц;2. Использует
purrr::walk()
для итерации по именам подтаблиц в нашем списке;3. Создает HTML-таблицу для каждой подтаблицы с помощью
kable()
;4. Добавляет стили с
kable_styling()
5. Выводит каждую таблицу в документ с помощью
cat()
6. Добавляет пустые строки между таблицами для лучшей читаемости.
Надеюсь, этот подход будет полезен в вашей работе с RMarkdown. Если у вас возникнут вопросы или вы захотите поделиться своими методами работы с данными, пишите в комментариях!
#заметки_по_R
Работа с динамическими именами столбцов в dplyr: sym(), syms() и оператор !!
Часто при работе с данными в R возникает необходимость обращаться к столбцам таблицы по их именам, которые могут передаваться как строки. Это может быть полезно, если имена столбцов не известны заранее или задаются динамически в функциях. В
Проблема:
Обычно в dplyr мы обращаемся к столбцам напрямую, как показано ниже:
Но что, если имена столбцов будут передаваться в виде строк, например через аргументы функции? Простое использование строк в
Решение: sym() и оператор !!
Функция
В этой функции:
Оператор
Работа с несколькими столбцами: syms()
Если вам нужно работать сразу с несколькими столбцами, то для преобразования списка строк в символы можно использовать функцию syms().
Здесь:
————————————
Использование функций
О подобных примерах рассказано в виньетке "Программирование с dplyr".
#заметки_по_R
Часто при работе с данными в R возникает необходимость обращаться к столбцам таблицы по их именам, которые могут передаваться как строки. Это может быть полезно, если имена столбцов не известны заранее или задаются динамически в функциях. В
dplyr
для таких задач существует механизм tidy evaluation, и одними из ключевых инструментов являются функции sym()
, syms()
и оператор !!
.Проблема:
Обычно в dplyr мы обращаемся к столбцам напрямую, как показано ниже:
library(dplyr)
data <- tibble(
Area = c('IT', 'Finance', NA),
Date = as.Date(c('2023-01-01', NA, '2023-03-15'))
)
# Фильтруем строки, где нет пропусков в столбцах 'Area' и 'Date'
filtered_data <- data %>%
filter(!is.na(Area), !is.na(Date))
Но что, если имена столбцов будут передаваться в виде строк, например через аргументы функции? Простое использование строк в
filter()
не сработает.Решение: sym() и оператор !!
Функция
sym()
преобразует строку в символ (символ — это объект, который может быть интерпретирован как имя переменной), а оператор !!
используется для развертывания этого символа в выражении. Давайте рассмотрим, как это работает:library(dplyr)
# Функция для фильтрации данных на основе имен столбцов, переданных как строки
filter_data <- function(data, col_name1, col_name2) {
col1 <- sym(col_name1)
col2 <- sym(col_name2)
data %>%
filter(!is.na(!!col1), !is.na(!!col2))
}
# Пример данных
data <- tibble(
Area = c('IT', 'Finance', NA),
Date = as.Date(c('2023-01-01', NA, '2023-03-15'))
)
# Фильтруем данные, используя имена столбцов как строки
filtered_data <- filter_data(data, 'Area', 'Date')
print(filtered_data)
В этой функции:
sym(col_name1)
и sym(col_name2)
преобразуют строки в символы, которые затем могут использоваться в dplyr::filter()
.Оператор
!!
разворачивает символ в выражении, позволяя использовать его как имя переменной в функции filter()
.Работа с несколькими столбцами: syms()
Если вам нужно работать сразу с несколькими столбцами, то для преобразования списка строк в символы можно использовать функцию syms().
library(dplyr)
# Функция для фильтрации нескольких столбцов
filter_multiple <- function(data, col_names) {
cols <- syms(col_names)
data %>%
filter(across(all_of(col_names), ~ !is.na(.)))
}
# Пример данных
data <- tibble(
Area = c('IT', 'Finance', NA),
Date = as.Date(c('2023-01-01', NA, '2023-03-15')),
Amount = c(1000, 2000, NA)
)
# Фильтруем строки, где нет пропусков в нескольких столбцах
filtered_data <- filter_multiple(data, c('Area', 'Date', 'Amount'))
print(filtered_data)
Здесь:
syms(col_names)
преобразует вектор строк в список символов.across()
вместе с all_of()
позволяет удобно применить фильтр ко всем указанным столбцам.————————————
Использование функций
sym()
, syms()
и оператора !!
— это мощный инструмент для написания гибкого и динамического кода в R. Он особенно полезен при работе с большими данными и пакетами вроде dplyr, когда имена столбцов не известны заранее или приходят из пользовательского ввода.О подобных примерах рассказано в виньетке "Программирование с dplyr".
#заметки_по_R
Релиз patchwork 1.3.0
Вышла версия
Также доступны более продвинутые возможности для компоновки графиков и таблиц. Например, можно использовать сложный макет с элементами разного размера:
Это позволяет гибко управлять макетом визуализации, комбинируя таблицы и графики разных типов.
Ссылки:
● Подробнее можно прочитать в оригинальной статье на Tidyverse Blog.
● Также ранее я уже рассказывал о пакете
#новости_и_релизы_по_R
Вышла версия
patchwork 1.3.0
, которая привнесла интересные возможности для работы с таблицами в графических композициях. Теперь можно легко интегрировать таблицы gt
с графиками, используя функции wrap_elements()
и wrap_table()
. Пример простого графика с таблицей:library(patchwork)
library(ggplot2)
library(gt)
p1 <- ggplot(airquality) +
geom_line(aes(x = Day, y = Temp, colour = month.name[Month])) +
labs(colour = "Month")
aq <- airquality[sample(nrow(airquality), 10), ]
p1 + wrap_table(aq, space = "free_y")
Также доступны более продвинутые возможности для компоновки графиков и таблиц. Например, можно использовать сложный макет с элементами разного размера:
p1 <- ggplot(mtcars) +
geom_point(aes(mpg, disp)) +
ggtitle('Scatter plot')
p2 <- ggplot(mtcars) +
geom_bar(aes(factor(cyl))) +
ggtitle('Bar plot')
layout <- c(
area(t = 1, l = 1, b = 2, r = 2),
area(t = 1, l = 3, b = 2, r = 3)
)
p1 + p2 + plot_layout(design = layout)
Это позволяет гибко управлять макетом визуализации, комбинируя таблицы и графики разных типов.
Ссылки:
● Подробнее можно прочитать в оригинальной статье на Tidyverse Blog.
● Также ранее я уже рассказывал о пакете
patchwork
в посте "Как расположить несколько ggplot2 графиков на одном изображении".#новости_и_релизы_по_R
R4marketing 6 лет
Ровно 6 лет назад, 1 ноября 2018 года, я анонсировал в Facebook запуск этого канала. Это было время, когда Telegram только набирал популярность как платформа для профессионального контента, и я решил создать пространство, где буду делиться знаниями и какими то заметками по языку R.
На данный момент в канале опубликовано 1256 постов, очень долгое время я держал темп в 1 пост каждый будний день, и не сбавлял его даже в периоды отпусков. Хотя сейчас темп публикаций уже не "пост каждый будний день", как было изначально, но я по-прежнему стараюсь делиться только действительно ценным контентом, который поможет вам в работе и профессиональном росте.
Спасибо каждому из вас за то, что остаётесь со мной все эти годы! Ваши комментарии, обратная связь и дискуссии делают этот канал живым и помогают развиваться всем нам.
Ровно 6 лет назад, 1 ноября 2018 года, я анонсировал в Facebook запуск этого канала. Это было время, когда Telegram только набирал популярность как платформа для профессионального контента, и я решил создать пространство, где буду делиться знаниями и какими то заметками по языку R.
На данный момент в канале опубликовано 1256 постов, очень долгое время я держал темп в 1 пост каждый будний день, и не сбавлял его даже в периоды отпусков. Хотя сейчас темп публикаций уже не "пост каждый будний день", как было изначально, но я по-прежнему стараюсь делиться только действительно ценным контентом, который поможет вам в работе и профессиональном росте.
Спасибо каждому из вас за то, что остаётесь со мной все эти годы! Ваши комментарии, обратная связь и дискуссии делают этот канал живым и помогают развиваться всем нам.
S7 0.2.0: Новый стандарт ООП в R
S7 — это гибкий и мощный инструмент для объектно-ориентированного программирования в R, предлагающий строгость S4 и простоту S3. Новая версия 0.2.0 усиливает производительность, вводит улучшенную совместимость с S3 и добавляет гибкие валидаторы. Проектирование и реализация S7 были совместными усилиями рабочей группы из R Consortium , включая представителей R-Core, Bioconductor, tidyverse/Posit, ROpenSci и более широкого сообщества R. В будущем разработчики планируют интеграцию S7 в базовый R.
Установите пакет, чтобы попробовать новый подход к ООП:
Основные возможности S7
1. Создание классов
S7 позволяет определять классы с четкими типами свойств. Для обеспечения корректности данных можно использовать валидаторы.
Пример:
2. Создание методов
Методы создаются через обобщенные функции (
Пример:
3. Совместимость с S3
S7 интегрируется с S3-методами, что облегчает переход на новую систему. Например, можно использовать существующие S3-классы как базовые.
4. Наследование классов
Создание иерархий классов позволяет расширять возможности базового класса.
Пример:
Производительность и планы на будущее
S7 разработан с учетом высокой производительности: проверки свойств реализованы на уровне C, что делает его подходящим для обработки больших объемов данных. В будущем планируется включить поддержку S7-классов в базовый R, что сделает их стандартом.
Почему стоит использовать S7?
Простота: Создание классов и методов не сложнее, чем в S3.
Надежность: Строгая типизация предотвращает ошибки.
Универсальность: Подходит для создания библиотек, построения API и работы с данными.
Ссылки:
● S7 0.2.0 (eng)
Так же про ООП в R
● ООП в языке R (часть 1): S3 классы
● ООП в языке R (часть 2): R6 классы
#новости_и_релизы_по_R
S7 — это гибкий и мощный инструмент для объектно-ориентированного программирования в R, предлагающий строгость S4 и простоту S3. Новая версия 0.2.0 усиливает производительность, вводит улучшенную совместимость с S3 и добавляет гибкие валидаторы. Проектирование и реализация S7 были совместными усилиями рабочей группы из R Consortium , включая представителей R-Core, Bioconductor, tidyverse/Posit, ROpenSci и более широкого сообщества R. В будущем разработчики планируют интеграцию S7 в базовый R.
Установите пакет, чтобы попробовать новый подход к ООП:
install.packages("S7")
Основные возможности S7
1. Создание классов
S7 позволяет определять классы с четкими типами свойств. Для обеспечения корректности данных можно использовать валидаторы.
Пример:
Range <- new_class("Range",
properties = list(
start = class_double,
end = class_double
),
validator = function(self) {
if (length(self@start) != 1) {
"@start must be length 1"
} else if (length(self@end) != 1) {
"@end must be length 1"
} else if (self@end < self@start) {
"@end must be greater than or equal to @start"
}
}
)
# Создаем корректный объект
valid_range <- new_object(Range, start = 1, end = 10)
print(valid_range)
# Проверка с некорректными данными
tryCatch(
new_object(Range, start = 10, end = 5),
error = function(e) message("Ошибка: ", e$message)
)
2. Создание методов
Методы создаются через обобщенные функции (
new_generic()
). Это упрощает настройку поведения для различных классов.Пример:
greeting <- new_generic("greeting", function(x) NULL)
method(greeting, Range) <- function(x) {
paste("Диапазон начинается с", x@start, "и заканчивается", x@end)
}
greeting(valid_range) # Диапазон начинается с 1 и заканчивается 10
3. Совместимость с S3
S7 интегрируется с S3-методами, что облегчает переход на новую систему. Например, можно использовать существующие S3-классы как базовые.
4. Наследование классов
Создание иерархий классов позволяет расширять возможности базового класса.
Пример:
Employee <- new_class("Employee", parent = Range, properties = list(
name = class_character
))
worker <- Employee(start = 9, end = 18, name = "Jane")
print(worker)
Производительность и планы на будущее
S7 разработан с учетом высокой производительности: проверки свойств реализованы на уровне C, что делает его подходящим для обработки больших объемов данных. В будущем планируется включить поддержку S7-классов в базовый R, что сделает их стандартом.
Почему стоит использовать S7?
Простота: Создание классов и методов не сложнее, чем в S3.
Надежность: Строгая типизация предотвращает ошибки.
Универсальность: Подходит для создания библиотек, построения API и работы с данными.
Ссылки:
● S7 0.2.0 (eng)
Так же про ООП в R
● ООП в языке R (часть 1): S3 классы
● ООП в языке R (часть 2): R6 классы
#новости_и_релизы_по_R
Мобильные приложения с R: революция благодаря webR
Мир R и мобильных технологий стал на шаг ближе с выходом
Что такое webR и в чем его уникальность?
Ключевые особенности
● Нет необходимости в R-сервере.
● Полноценная работа с R-кодом в мобильной среде.
● Возможность использовать стандартные функции R для анализа данных и визуализации.
● Эта технология изменяет представление о том, где и как можно применять R, делая его доступным для разработчиков мобильных приложений.
Почему это важно?
До появления
● Ограниченная функциональность: отсутствие доступа к API устройства, таких как камера, вибрация, или геолокация.
● Нет автономности: такие приложения требовали постоянного подключения к серверу.
● Сложности с установкой: их нельзя было загрузить из App Store или Google Play.
● Устанавливаются через магазины приложений.
● Работают офлайн.
● Интегрируют функции смартфона.
Пример реализации: Игра на основе R
ThinkR представили рабочий прототип — мобильное приложение с интеграцией R-кода. Это игра, где пользователи угадывают, к какому пакету R принадлежит случайная функция.
Как работает приложение:
● Оно выбирает три случайных пакета из установленных.
● Генерирует функцию из одного из них.
● Пользователь угадывает, к какому пакету она относится.
Функционал включает:
● Локальное хранение данных о попытках пользователя в SQLite.
● Визуализацию прогресса на графиках.
● Поддержку вибрации, автономного режима и других мобильных API.
Этот проект демонстрирует не только возможности webR, но и задает направление для будущих приложений.
Что дальше?
Разработчики ThinkR работают над выпуском приложения в App Store и Google Play. Этот проект — шаг к тому, чтобы сделать R универсальным инструментом, доступным не только для серверных решений, но и для мобильной разработки.
Если вы хотите быть в курсе новостей, посетите официальный сайт ThinkR, где можно подписаться на уведомления о выходе приложения.
————————————
#новости_и_релизы_по_R
Мир R и мобильных технологий стал на шаг ближе с выходом
webR
— WebAssembly-компиляции R. Эта технология позволяет запускать R-код прямо в JavaScript-средах, открывая новые возможности для создания мобильных приложений. В этом посте разбираем, как это работает и что это значит для разработчиков.Что такое webR и в чем его уникальность?
webR
— это специальная версия R, адаптированная для работы в WebAssembly. Если раньше R использовался преимущественно для серверных приложений (например, через Shiny
), то теперь его можно внедрять прямо в браузеры и мобильные устройства.Ключевые особенности
webR
:● Нет необходимости в R-сервере.
● Полноценная работа с R-кодом в мобильной среде.
● Возможность использовать стандартные функции R для анализа данных и визуализации.
● Эта технология изменяет представление о том, где и как можно применять R, делая его доступным для разработчиков мобильных приложений.
Почему это важно?
До появления
webR
мобильные приложения, использующие R, в основном реализовывались через Shiny
и shinyMobile
. Однако такие решения имели ряд ограничений:● Ограниченная функциональность: отсутствие доступа к API устройства, таких как камера, вибрация, или геолокация.
● Нет автономности: такие приложения требовали постоянного подключения к серверу.
● Сложности с установкой: их нельзя было загрузить из App Store или Google Play.
webR
решает эти проблемы, позволяя создавать настоящие нативные мобильные приложения, которые:● Устанавливаются через магазины приложений.
● Работают офлайн.
● Интегрируют функции смартфона.
Пример реализации: Игра на основе R
ThinkR представили рабочий прототип — мобильное приложение с интеграцией R-кода. Это игра, где пользователи угадывают, к какому пакету R принадлежит случайная функция.
Как работает приложение:
● Оно выбирает три случайных пакета из установленных.
● Генерирует функцию из одного из них.
● Пользователь угадывает, к какому пакету она относится.
Функционал включает:
● Локальное хранение данных о попытках пользователя в SQLite.
● Визуализацию прогресса на графиках.
● Поддержку вибрации, автономного режима и других мобильных API.
Этот проект демонстрирует не только возможности webR, но и задает направление для будущих приложений.
Что дальше?
Разработчики ThinkR работают над выпуском приложения в App Store и Google Play. Этот проект — шаг к тому, чтобы сделать R универсальным инструментом, доступным не только для серверных решений, но и для мобильной разработки.
Если вы хотите быть в курсе новостей, посетите официальный сайт ThinkR, где можно подписаться на уведомления о выходе приложения.
————————————
webR
— это революционная технология, которая может значительно изменить подход к созданию приложений. Это важный шаг для популяризации R за пределами традиционных областей его применения.#новости_и_релизы_по_R
Оптимизация функций в R: переосмысление аргументов с S7
Функции с множеством аргументов могут быть трудными для использования и сопровождения. Чтобы решить эту проблему, можно использовать подход с объектами опций (options objects), применяя возможности системы S7 (новая реализация ООП в R о которой мы недавно говорили). Рассмотрим пример, как можно переработать функцию readr::read_csv().
Проблема: слишком много параметров
Функция
● Сократить количество аргументов в функции.
● Улучшить читаемость и поддерживаемость кода.
● Обеспечить строгую типизацию параметров.
Шаг 1: Создание свойств с помощью new_property()
Для начала определим свойства, которые будут использоваться в нашем объекте опций. Например, свойство для параметра `locale:
Этот код задает значения по умолчанию и проверяет, что все элементы
Подобным образом мы можем создать объекты опций для большинства других аргументов:
●
●
●
●
●
●
●
●
●
●
●
●
●
Шаг 2: Создание класса с помощью new_class()
Теперь создадим класс для объекта опций, который объединяет все свойства, включая
Такой подход позволяет гибко задавать опции с использованием строгой типизации.
Шаг 3: Переопределение функции read_csv()
После создания объекта опций можно переопределить функцию read_csv() для работы с новым подходом:
Вместо передачи множества опциональных аргументов пользователь может передать объект
————————————
Использование объектов опций с
Ссылки:
● В основе поста лежит статья "S7 & Options objects"
#заметки_по_R
Функции с множеством аргументов могут быть трудными для использования и сопровождения. Чтобы решить эту проблему, можно использовать подход с объектами опций (options objects), применяя возможности системы S7 (новая реализация ООП в R о которой мы недавно говорили). Рассмотрим пример, как можно переработать функцию readr::read_csv().
Проблема: слишком много параметров
Функция
readr::read_csv()
имеет более 20 аргументов, многие из которых редко используются, например, locale
, skip
, na
. Перенос менее востребованных настроек в объект опций позволяет:● Сократить количество аргументов в функции.
● Улучшить читаемость и поддерживаемость кода.
● Обеспечить строгую типизацию параметров.
Шаг 1: Создание свойств с помощью new_property()
Для начала определим свойства, которые будут использоваться в нашем объекте опций. Например, свойство для параметра `locale:
library(S7)
.locale <- new_property(
class_list,
default = readr::default_locale(),
validator = function(value) {
dnames <- value$date_names
invalid <- !rlang::is_character(dnames$mon, n = 12) ||
!rlang::is_character(dnames$mon_ab, n = 12) ||
!rlang::is_character(dnames$day, n = 7) ||
!rlang::is_character(dnames$day_ab, n = 7) ||
!rlang::is_character(dnames$am_pm, n = 2) || !rlang::is_scalar_character(value$date_format) || !rlang::is_scalar_character(value$time_format) || !rlang::is_scalar_character(value$decimal_mark) || !rlang::is_scalar_character(value$grouping_mark) || !rlang::is_scalar_character(value$tz) || !rlang::is_scalar_character(value$encoding)
if (invalid) {
"expected `locale` object"
}
}
)
Этот код задает значения по умолчанию и проверяет, что все элементы
locale
имеют правильный тип.Подобным образом мы можем создать объекты опций для большинства других аргументов:
●
na
●
quote
●
comment
●
trim_ws
●
skip
●
n_max
●
guess_max
●
name_repair
●
num_threads
●
progress
●
show_col_types
●
skip_empty_rows
●
lazy
Шаг 2: Создание класса с помощью new_class()
Теперь создадим класс для объекта опций, который объединяет все свойства, включая
locale
, na
, trim_ws
и другие:class_readr_opts <- new_class(
"readr_opts",
properties = list(
locale = .locale,
na = .na,
quote = .quote,
comment = .comment,
trim_ws = .trim_ws,
skip = .skip,
n_max = .n_max,
guess_max = .guess_max,
name_repair = .name_repair,
num_threads = .num_threads,
progress = .progress,
show_col_types = .show_col_types,
skip_empty_rows = .skip_empty_rows,
lazy = .lazy
)
)
opts <- class_readr_opts()
opts
Такой подход позволяет гибко задавать опции с использованием строгой типизации.
Шаг 3: Переопределение функции read_csv()
После создания объекта опций можно переопределить функцию read_csv() для работы с новым подходом:
read_csv <- function(
file,
col_names = TRUE,
col_types = NULL,
col_select = NULL,
id = NULL,
options = class_readr_opts()
) {
# function logic
}
Вместо передачи множества опциональных аргументов пользователь может передать объект
options
, упростив вызов и настройку функции.————————————
Использование объектов опций с
S7
позволяет уменьшить сложность функций, сделать их более читаемыми и строго типизированными. Такой подход особенно полезен при разработке библиотек и сложных API.Ссылки:
● В основе поста лежит статья "S7 & Options objects"
#заметки_по_R
Elmer: Универсальный инструмент для работы с LLM через R
Ранее я уже рассказывал о пакете
1. Что такое Elmer?
● Мульти-провайдерная поддержка, на данный момент реализована поддержка:
● Anthropic’s Claude:
● AWS Bedrock:
● Azure OpenAI:
● Databricks:
● GitHub model marketplace:
● Google Gemini:
● Groq:
● Ollama: chat_ollama()`.
● OpenAI: `chat_openai()`.
● perplexity.ai: `chat_perplexity()`.
● Snowflake Cortex: `chat_cortex()`.
Кстати, создатели `elmer` утверждают, что для генерации кода по их мнению лучше всего себя проявляет Anthropic’s Claude, т.е. Claude.ai, и я по этому поводу тоже уже своими наблюдениями делился.
● Гибкость в настройках промптов и диалогов.
● Извлечение структурированных данных из текста.
● Поддержка асинхронных вызовов для повышения производительности.
Эти функции делают Elmer мощным инструментом для анализа данных, автоматизации задач и разработки приложений.
2. Установка
Установите
3. Управление диалогами
Чат-объекты в
4. Программные возможности
4.1. Интерактивный режим: Используйте R-консоль для живого общения:
4.2. Программный режим: Создайте сценарий, возвращающий результаты для дальнейшей обработки:
4.3. Асинхронные вызовы: Используйте асинхронный API для ускорения обработки больших объемов данных.
5. Извлечение структурированных данных
● Анализ отзывов клиентов.
● Извлечение рецептов и их структурирование.
● Геокодирование адресов.
Пример:
6. Работа с токенами
Один запрос к модели GPT-4o mini может стоить от $0.15 за миллион токенов, что делает использование API доступным для экспериментов.
7. Рекомендации по промптам
Правильный дизайн промптов — ключ к качественным ответам. Например:
● Укажите системные инструкции для кастомизации:
● Используйте промпты для автоматизации, например, создания документации на основе README вашего пакета.
8. Кейсы использования
Elmer отлично подходит для:
● Создания чат-ботов для поддержки пользователей.
● Прототипирования инструментов: автоматизация анализа данных и отчетности.
● Кастомизации работы LLM под специфические задачи.
————————————
Пока что
#новости_и_релизы_по_R
Ранее я уже рассказывал о пакете
Elmer
, который позволяет взаимодействовать с большими языковыми моделями (LLM) прямо из R. Сегодня мы углубимся в детали его функционала и возможностей, чтобы вы могли максимально эффективно использовать этот инструмент.1. Что такое Elmer?
Elmer
— это пакет из экосистемы tidyverse
, созданный для удобного использования LLM API. Его основные преимущества:● Мульти-провайдерная поддержка, на данный момент реализована поддержка:
● Anthropic’s Claude:
chat_claude()
.● AWS Bedrock:
chat_bedrock()
.● Azure OpenAI:
chat_azure()
.● Databricks:
chat_databricks()
.● GitHub model marketplace:
chat_github()
.● Google Gemini:
chat_gemini()
.● Groq:
chat_groq()
.● Ollama: chat_ollama()`.
● OpenAI: `chat_openai()`.
● perplexity.ai: `chat_perplexity()`.
● Snowflake Cortex: `chat_cortex()`.
Кстати, создатели `elmer` утверждают, что для генерации кода по их мнению лучше всего себя проявляет Anthropic’s Claude, т.е. Claude.ai, и я по этому поводу тоже уже своими наблюдениями делился.
● Гибкость в настройках промптов и диалогов.
● Извлечение структурированных данных из текста.
● Поддержка асинхронных вызовов для повышения производительности.
Эти функции делают Elmer мощным инструментом для анализа данных, автоматизации задач и разработки приложений.
2. Установка
Установите
elmer
с помощью:pak::pak("tidyverse/elmer")
3. Управление диалогами
Чат-объекты в
elmer
сохраняют историю, что упрощает многозадачные сценарии:chat <- chat_openai(model = "gpt-4o-mini")
chat$chat("Кто создал R?")
#> "R был создан Россом Ихакой и Робертом Джентлменом."
4. Программные возможности
elmer
поддерживает несколько способов взаимодействия с LLM:4.1. Интерактивный режим: Используйте R-консоль для живого общения:
live_console(chat)
4.2. Программный режим: Создайте сценарий, возвращающий результаты для дальнейшей обработки:
my_function <- function() {
chat <- chat_openai(model = "gpt-4o-mini")
chat$chat("Что такое функциональное программирование?")
}
4.3. Асинхронные вызовы: Используйте асинхронный API для ускорения обработки больших объемов данных.
5. Извлечение структурированных данных
elmer
позволяет преобразовывать текст в удобный формат для анализа:● Анализ отзывов клиентов.
● Извлечение рецептов и их структурирование.
● Геокодирование адресов.
Пример:
chat$chat("Выдели ключевые слова из текста")
6. Работа с токенами
elmer
помогает отслеживать использование токенов для оптимизации затрат:chat$chat("Кто создал R?")
chat
token_usage()
Один запрос к модели GPT-4o mini может стоить от $0.15 за миллион токенов, что делает использование API доступным для экспериментов.
7. Рекомендации по промптам
Правильный дизайн промптов — ключ к качественным ответам. Например:
● Укажите системные инструкции для кастомизации:
chat <- chat_openai(system_prompt = "Отвечай всегда кратко и на русском языке.")
● Используйте промпты для автоматизации, например, создания документации на основе README вашего пакета.
8. Кейсы использования
Elmer отлично подходит для:
● Создания чат-ботов для поддержки пользователей.
● Прототипирования инструментов: автоматизация анализа данных и отчетности.
● Кастомизации работы LLM под специфические задачи.
————————————
elmer
открывает новые горизонты для работы с LLM в R. Это не только инструмент для экспериментов, но и мощное средство для интеграции ИИ в ваши проекты. Узнайте больше из официальной документации.Пока что
elmer
по прежнему находится в активной стадии разработки, текущая версия 0.0.0.9000, но будем следить за этим процессом, и в ближайшее время буду ещё делиться информацией об этом проекте.#новости_и_релизы_по_R
httr2 1.1.0
Команда Хэдли продолжает развивать
В версии 1.1.0 появилось несколько значительных улучшений: поддержка потоковой передачи данных, новые инструменты для работы с URL, улучшенная интеграция с AWS и многое другое.
Разберем ключевые нововведения и примеры их использования.
————————————
1. Потоковая передача данных
Новая функция
Пример создания запроса с потоковой передачей:
Читаем данные частями:
Для обработки построчных данных (
2. Работа с URL
Появились удобные инструменты для манипуляции URL.
2.1. Изменение компонентов URL
2.2. Изменение параметров запроса
2.3. Работа с относительными URL
3. Поддержка AWS
Теперь httr2 позволяет легко подписывать запросы для AWS:
Это упрощает работу с сервисами Amazon, такими как S3, DynamoDB, API Gateway и другими.
4. Дополнительные улучшения
● Кэширование: Оптимизирована система кэширования запросов.
● Обработка ошибок: Теперь сообщения об ошибках стали информативнее.
● Поддержка OAuth: Улучшена аутентификация через OAuth.
В основе поста лежит статья "httr2 1.1.0".
#новости_и_релизы_по_R
Команда Хэдли продолжает развивать
httr2
— современный пакет для работы с веб-API в R, с момента его появления все новые пакеты я пишу именно на его основе. В версии 1.1.0 появилось несколько значительных улучшений: поддержка потоковой передачи данных, новые инструменты для работы с URL, улучшенная интеграция с AWS и многое другое.
Разберем ключевые нововведения и примеры их использования.
————————————
1. Потоковая передача данных
Новая функция
req_perform_connection()
улучшает поддержку потоковой передачи ответов, что особенно полезно при работе с LLM и обработке больших объемов данных.Пример создания запроса с потоковой передачей:
library(httr2)
req <- request(example_url()) |> req_template("/stream-bytes/:n", n = 10240)
resp <- req_perform_connection(req)
resp
#> <httr2_response>
#> GET http://127.0.0.1:49283/stream-bytes/10240
#> Status: 200 OK
#> Content-Type: application/octet-stream
#> Body: Streaming connection
Читаем данные частями:
while (!resp_stream_is_complete(resp)) {
bytes <- resp_stream_raw(resp, kb = 2)
cat("Downloaded ", length(bytes), " bytes\n", sep = "")
}
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 0 bytes
Для обработки построчных данных (
resp_stream_lines()
) и событий сервера (resp_stream_sse()
) добавлены отдельные функции.2. Работа с URL
Появились удобные инструменты для манипуляции URL.
2.1. Изменение компонентов URL
url_modify("https://example.com", hostname = "github.com")
#> [1] "https://github.com/"
2.2. Изменение параметров запроса
url_modify_query("http://example.com?a=1&b=2", a = 10)
#> [1] "http://example.com/?b=2&a=10"
2.3. Работа с относительными URL
url_modify_relative("https://example.com/a/b/c.html", "/d/e/f.html")
#> [1] "https://example.com/d/e/f.html"
3. Поддержка AWS
Теперь httr2 позволяет легко подписывать запросы для AWS:
req <- request("https://s3.amazonaws.com/bucketname") |>
req_sign_aws(
access_key = "your-access-key",
secret_key = "your-secret-key",
service = "s3",
region = "us-east-1"
)
Это упрощает работу с сервисами Amazon, такими как S3, DynamoDB, API Gateway и другими.
4. Дополнительные улучшения
● Кэширование: Оптимизирована система кэширования запросов.
● Обработка ошибок: Теперь сообщения об ошибках стали информативнее.
● Поддержка OAuth: Улучшена аутентификация через OAuth.
В основе поста лежит статья "httr2 1.1.0".
#новости_и_релизы_по_R
Рекурсивные операции в R: Магия функции accumulate()
1. Пример 1: Накопительная сумма
Как это работает?:
● Начинает с первого элемента (1)
● Каждый следующий шаг - сумма предыдущего накопленного результата и текущего элемента
● 1 → (1+2=3) → (3+3=6) → (6+4=10) → (10+5=15)
Пример 2: Генерация последовательности Фибоначчи
Детали реализации:
●
● На каждой итерации берем второй элемент и сумму
● Создаем классическую последовательность Фибоначчи
Пример 3: Сложная трансформация данных
Сценарий:
● Накапливаем статистику по транзакциям
● Считаем общую сумму, налоги, количество обработанных записей
● Используем аккумуляцию для последовательной обработки
————————————
В пакете
Тему циклов и функционалов я подробно рассматривал в бесплатном курсе "Циклы и функционалы в языке R", так что если есть желание погрузится в эту тему то велкам!
#заметки_по_R
accumulate()
из пакета purrr
- потрясающий инструмент для выполнения рекурсивных вычислений в R. Давайте рассмотрим три последовательных примера от простого к сложному.1. Пример 1: Накопительная сумма
library(purrr)
# Простейший пример накопления суммы
numbers <- 1:5
result <- accumulate(numbers, `+`)
# Результат: [1] 1 3 6 10 15
Как это работает?:
● Начинает с первого элемента (1)
● Каждый следующий шаг - сумма предыдущего накопленного результата и текущего элемента
● 1 → (1+2=3) → (3+3=6) → (6+4=10) → (10+5=15)
Пример 2: Генерация последовательности Фибоначчи
fibonacci <- accumulate(1:10, function(acc, _) {
c(acc[2], sum(acc))
}, .init = c(0, 1))
# Результат: последовательность Фибоначчи
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Детали реализации:
●
.init
устанавливает начальное состояние● На каждой итерации берем второй элемент и сумму
● Создаем классическую последовательность Фибоначчи
Пример 3: Сложная трансформация данных
library(dplyr)
# Имитация сложного бизнес-процесса
transactions <- list(
list(amount = 100, tax_rate = 0.1),
list(amount = 200, tax_rate = 0.15),
list(amount = 150, tax_rate = 0.12)
)
total_calculation <- accumulate(transactions, function(acc, transaction) {
list(
total_amount = acc$total_amount + transaction$amount,
total_tax = acc$total_tax + (transaction$amount * transaction$tax_rate),
processed_count = acc$processed_count + 1
)
}, .init = list(
total_amount = 0,
total_tax = 0,
processed_count = 0
))
# Финальный результат в последнем элементе
final_result <- total_calculation[[length(total_calculation)]]
Сценарий:
● Накапливаем статистику по транзакциям
● Считаем общую сумму, налоги, количество обработанных записей
● Используем аккумуляцию для последовательной обработки
————————————
В пакете
purrr
помимо accumulate()
есть множество других полезных функционалов, которые могут заменить вам циклы for
, и сделать ваш код более читабельным и оптимизированным. Тему циклов и функционалов я подробно рассматривал в бесплатном курсе "Циклы и функционалы в языке R", так что если есть желание погрузится в эту тему то велкам!
#заметки_по_R
Разбираем функцию exec() из пакета rlang
Друзья! Сегодня разберём функцию
Что такое exec()?
Базовый синтаксис:
Практические примеры использования
1. Работа с API
2. Генерация отчётов
3. Обработка данных с динамическими параметрами
Советы
● Кэширование параметров
● Валидация параметров
————————————
● Работаете с конфигурируемыми параметрами
● Создаёте wrapper-функции для API
● Автоматизируете генерацию отчётов
● Обрабатываете данные из разных источников
#заметки_по_R
Друзья! Сегодня разберём функцию
exec()
. Если вы работаете с API, создаёте отчёты или автоматизируете рабочие процессы - этот инструмент значительно упростит вашу жизнь.Что такое exec()?
exec()
- это современная альтернатива базовой функции do.call()
. Она позволяет динамически вызывать функции с аргументами, которые хранятся в списке или других структурах данных.Базовый синтаксис:
exec(fn, !!!args)
Практические примеры использования
1. Работа с API
# Конфигурация для разных API endpoints
api_configs <- list(
jira = list(
base_url = "https://jira.company.com",
auth = list(user = "user", token = "token"),
project = "PROJ"
),
gitlab = list(
base_url = "https://gitlab.company.com",
private_token = "token",
project_id = 123
)
)
# Функция для гибкого создания API запросов
create_api_request <- function(service, endpoint, ...) {
base_params <- api_configs[[service]]
extra_params <- list(...)
exec(
httr::GET,
url = file.path(base_params$base_url, endpoint),
!!!base_params,
!!!extra_params
)
}
# Использование
create_api_request("jira", "issues", query = list(status = "Open"))
2. Генерация отчётов
# Параметры для разных типов отчётов
report_params <- list(
daily = list(
period = "day",
metrics = c("users", "revenue"),
format = "xlsx",
email_to = "[email protected]"
),
weekly = list(
period = "week",
metrics = c("users", "revenue", "retention"),
format = "pdf",
email_to = c("[email protected]", "[email protected]")
)
)
generate_report <- function(report_type, additional_params = list()) {
base_params <- report_params[[report_type]]
# Комбинируем базовые параметры с дополнительными
exec(
create_report,
!!!base_params,
!!!additional_params,
timestamp = Sys.time()
)
}
# Использование
generate_report("daily", list(department = "sales"))
3. Обработка данных с динамическими параметрами
Советы
● Кэширование параметров
# Создаём кэш часто используемых параметров
cached_params <- memoise::memoise(function(report_type) {
# Здесь может быть загрузка из базы данных или API
report_params[[report_type]]
})
generate_cached_report <- function(report_type, ...) {
params <- cached_params(report_type)
exec(create_report, !!!params, ...)
}
● Валидация параметров
validate_and_exec <- function(fn, args) {
required_args <- names(formals(fn))
missing_args <- setdiff(required_args, names(args))
if (length(missing_args) > 0) {
stop("Missing required arguments: ",
paste(missing_args, collapse = ", "))
}
exec(fn, !!!args)
}
————————————
exec()
- это не просто замена do.call()
, а мощный инструмент для создания гибкого и поддерживаемого кода. Особенно полезен когда:● Работаете с конфигурируемыми параметрами
● Создаёте wrapper-функции для API
● Автоматизируете генерацию отчётов
● Обрабатываете данные из разных источников
#заметки_по_R
Гибкий импорт в R 4.5 с помощью use()
Всем привет, давно я тут ничего не писал, надо понемногу исправляться.
11 апреля 2025 года вышла новая версия R — R 4.5.0 “How About a Twenty-Six”. Как обычно, разработчики завезли кучу полезных мелочей и парочку реально классных фич. Одна из самых интересных — это функция
Если ты когда-нибудь писал на Python, то помнишь, как там удобно можно импортировать только нужные функции:
В R же приходилось выбирать между:
Или
Проблема второго способа в том, что разные пакеты могут переопределять друг друга. Яркий пример —
А если попробовать вызвать что-то не из списка, например
#новости_и_релизы_по_R
Всем привет, давно я тут ничего не писал, надо понемногу исправляться.
11 апреля 2025 года вышла новая версия R — R 4.5.0 “How About a Twenty-Six”. Как обычно, разработчики завезли кучу полезных мелочей и парочку реально классных фич. Одна из самых интересных — это функция
use()
, которой давно в R не хватало.Если ты когда-нибудь писал на Python, то помнишь, как там удобно можно импортировать только нужные функции:
from numpy import array
array([1, 2, 3])
В R же приходилось выбирать между:
dplyr::filter(penguins, bill_len > 40)
Или
library(dplyr)
filter(penguins, bill_len > 40)
Проблема второго способа в том, что разные пакеты могут переопределять друг друга. Яркий пример —
filter()
из dplyr
и stats
. Эту проблему можно было решить с помощью таких пакетов как conflicted
, modules
и import
о чём я уже как то рассказывал тут. Так вот, в R 4.5.0 подвезли use()
- аккуратный способ подключать только нужные функции из пакета:use("dplyr", c("filter", "select"))
penguins |>
filter(bill_len > 40) |>
select(species:bill_dep)
А если попробовать вызвать что-то не из списка, например
n_distinct()
, то R честно скажет, что такой функции в текущем окружении нет.#новости_и_релизы_по_R
Новый видеоурок: Использование LLM-моделей в языке R — на практике и бесплатно
В этом видео я показываю реальный кейс из своей работы, где мы встроили LLM-модели (на примере Gemini) в ежедневные процессы аналитики — всё с помощью языка R.
Весь показанный функционал реализован на 100% бесплатно, без покупки подписок или платных API.
На основе пакетов
В этом видео вы узнаете:
● Как бесплатно получить API-ключ Gemini и подключить его к R.
● Как настраивать и использовать объект chat.
● Как с помощью LLM извлекать структурированные данные из текста.
● Как добавить в чат сторонние API как "инструменты".
● Как построить простой, но мощный графический интерфейс с shinychat.
● Как дообучить модель своими данными — для точных ответов под ваш контекст.
Тайм коды:
00:00 О чём это видео
01:05 Кейс практического внедрения AI в рабочие процессы
06:49 Введение в пакет
08:20 Как бесплатно сгенерировать API ключ для работы с Gemini API
09:05 Аргументы конструктора LLM чатов
11:07 Создаём объект chat
13:01 Методы объекта chat
14:30 Отправляем запрос в LLM
17:03 Извлечение структурированных данных из текста
24:15 Добавляем в чат инструменты, работа со сторонними API
28:17 Создаём графический интерфейс для нашего чата с помощью
31:02 Как дообучить модель своими данными
33:50 Заключение
Ссылки:
- Код продемонстрированный в видео
#видео_уроки_по_R
В этом видео я показываю реальный кейс из своей работы, где мы встроили LLM-модели (на примере Gemini) в ежедневные процессы аналитики — всё с помощью языка R.
Весь показанный функционал реализован на 100% бесплатно, без покупки подписок или платных API.
На основе пакетов
ellmer
и shinychat
я шаг за шагом объясняю, как создать умного чат-бота, обрабатывать текст, подключать сторонние API и даже дообучать модель под себя.В этом видео вы узнаете:
● Как бесплатно получить API-ключ Gemini и подключить его к R.
● Как настраивать и использовать объект chat.
● Как с помощью LLM извлекать структурированные данные из текста.
● Как добавить в чат сторонние API как "инструменты".
● Как построить простой, но мощный графический интерфейс с shinychat.
● Как дообучить модель своими данными — для точных ответов под ваш контекст.
Тайм коды:
00:00 О чём это видео
01:05 Кейс практического внедрения AI в рабочие процессы
06:49 Введение в пакет
ellmer
08:20 Как бесплатно сгенерировать API ключ для работы с Gemini API
09:05 Аргументы конструктора LLM чатов
11:07 Создаём объект chat
13:01 Методы объекта chat
14:30 Отправляем запрос в LLM
17:03 Извлечение структурированных данных из текста
24:15 Добавляем в чат инструменты, работа со сторонними API
28:17 Создаём графический интерфейс для нашего чата с помощью
shinychat
31:02 Как дообучить модель своими данными
33:50 Заключение
Ссылки:
- Код продемонстрированный в видео
#видео_уроки_по_R
YouTube
Как использовать искусственный интеллект (ChatGPT / Gemini / Claude) в R: от ellmer до shinychat
В этом видео я покажу, как использовать большие языковые модели (LLM) в языке R, чтобы внедрить искусственный интеллект прямо в повседневные рабочие процессы аналитика.
Разберём реальный кейс автоматизации задач с помощью LLM, изучим работу с пакетом ellmer…
Разберём реальный кейс автоматизации задач с помощью LLM, изучим работу с пакетом ellmer…
Опубликовал текстовую версию урока об использовании LLM моделей в R
Для тех кому текст лучше воспринимается опубликовал статью на основе урока "Использование LLM-моделей в языке R — на практике и бесплатно".
Содержание:
1. Как мы используем LLM в рабочих процессах
2. Генерация API ключа для работы с LLM
3. Работа с LLM в R
4. Как с помощью LLM извлекать структурированные данные из текста
5. Добавляем в чат инструменты
6. Создаём Shiny интерфейс для чата
7. Как дообучить модель своими данными
8. Заключение
#статьи_по_R
Для тех кому текст лучше воспринимается опубликовал статью на основе урока "Использование LLM-моделей в языке R — на практике и бесплатно".
Содержание:
1. Как мы используем LLM в рабочих процессах
2. Генерация API ключа для работы с LLM
3. Работа с LLM в R
4. Как с помощью LLM извлекать структурированные данные из текста
5. Добавляем в чат инструменты
6. Создаём Shiny интерфейс для чата
7. Как дообучить модель своими данными
8. Заключение
#статьи_по_R
Новый видеоурок: Интеграция LLM моделей в Telegram-ботов на R
В этом видео я расскажу, как интегрировать искусственный интеллект в Telegram-бота, используя язык R и пакеты
В видео вы увидите:
● Как сгенерировать API-ключ для работы с LLM
● Как использовать пакет
● Как извлекать данные из текста и классифицировать сообщения
● Как интегрировать внешние API через LLM
● Как подключить LLM модель к вашему боту
● Как сохранить состояние чата между сессиями
● Как дообучить бота своими данными
Материал частично дублирует урок по
Тайм коды:
00:00 О чём это видео
00:46 Генерация API ключа
02:20 Введение в пакет ellmer
03:20 Создаём объект чата
06:44 Извлечение структурированных данных их текста с помощью LLM моделей
10:35 Классификация текста с помощью LLM моделей
13:53 Интеграция LLM моделей со сторонними API
18:33 Как интегрировать LLM модель в telegram бота
23:27 Как сохранять состояние чатов между разными сессиями бота
26:24 Как дообучить telegram бота своими данными
28:58 Заключение
Ссылки:
- Код продемонстрированный в видео
#видео_уроки_по_R
В этом видео я расскажу, как интегрировать искусственный интеллект в Telegram-бота, используя язык R и пакеты
telegram.bot
и ellmer
.В видео вы увидите:
● Как сгенерировать API-ключ для работы с LLM
● Как использовать пакет
ellmer
для общения с LLM моделями● Как извлекать данные из текста и классифицировать сообщения
● Как интегрировать внешние API через LLM
● Как подключить LLM модель к вашему боту
● Как сохранить состояние чата между сессиями
● Как дообучить бота своими данными
Материал частично дублирует урок по
ellmer
+ shiny
, кто его видел можете начинать просмотр этого видео сразу с 18 минуты.Тайм коды:
00:00 О чём это видео
00:46 Генерация API ключа
02:20 Введение в пакет ellmer
03:20 Создаём объект чата
06:44 Извлечение структурированных данных их текста с помощью LLM моделей
10:35 Классификация текста с помощью LLM моделей
13:53 Интеграция LLM моделей со сторонними API
18:33 Как интегрировать LLM модель в telegram бота
23:27 Как сохранять состояние чатов между разными сессиями бота
26:24 Как дообучить telegram бота своими данными
28:58 Заключение
Ссылки:
- Код продемонстрированный в видео
#видео_уроки_по_R
YouTube
Как встроить LLM модели (ChatGPT / Claude / Gemini) в Telegram-бота на языке R
В этом видео я покажу, как интегрировать LLM модели в Telegram-ботов, используя язык программирования R и пакеты telegram.bot и ellmer.
Мы пройдем весь путь от генерации API-ключа до создания продвинутого бота, который умеет:
● Извлекать структурированные…
Мы пройдем весь путь от генерации API-ключа до создания продвинутого бота, который умеет:
● Извлекать структурированные…
Добавил главу про интеграцию LLM моделей в telegram ботов в учебник "Разработка Telegram ботов на языке R"
Содержание главы:
1. Как мы используем LLM в рабочих процессах
2. Генерация API ключа
3. Работа с LLM в R
3.1. Создание чата и отправка запроса
3.2. Извлечение структурированных данных из текста
3.3. Добавление в чат инструментов
4. Интеграция LLM модели в бот
4.1. Дообучение бота на своих данных
5. Заключение
Если вдруг кто впервые об этом учебнике слышит, то ниже его полное содержание:
1. Создаём бота и отправляем с его помощью сообщения в telegram
2. Добавляем боту поддержку команд и фильтры сообщений, класс Updater
3. Как добавить боту поддержку клавиатуры
4. Построение последовательного, логического диалога с ботом
5. Интегрируем в бота искусственный интеллект
6. Управление правами пользователей бота
7. Повышаем стабильность работы бота
8. Добавляем боту асинхронность
9. Упаковываем бота в Docker контейнер
10. Разворачиваем бота в облачных сервисах
Т.е. по этому учебнику вы с нуля научитесь писать telegram ботов любой сложности, и разворачивать их в некоторых облачных платформах или на своём сервере.
#учебники_по_R
Содержание главы:
1. Как мы используем LLM в рабочих процессах
2. Генерация API ключа
3. Работа с LLM в R
3.1. Создание чата и отправка запроса
3.2. Извлечение структурированных данных из текста
3.3. Добавление в чат инструментов
4. Интеграция LLM модели в бот
4.1. Дообучение бота на своих данных
5. Заключение
Если вдруг кто впервые об этом учебнике слышит, то ниже его полное содержание:
1. Создаём бота и отправляем с его помощью сообщения в telegram
2. Добавляем боту поддержку команд и фильтры сообщений, класс Updater
3. Как добавить боту поддержку клавиатуры
4. Построение последовательного, логического диалога с ботом
5. Интегрируем в бота искусственный интеллект
6. Управление правами пользователей бота
7. Повышаем стабильность работы бота
8. Добавляем боту асинхронность
9. Упаковываем бота в Docker контейнер
10. Разворачиваем бота в облачных сервисах
Т.е. по этому учебнику вы с нуля научитесь писать telegram ботов любой сложности, и разворачивать их в некоторых облачных платформах или на своём сервере.
#учебники_по_R
ellmer 0.2.0
3 предыдущие поста в канале так или иначе были связаны с пакетом
Breaking changes
● Изменения в преобразовании JSON → R
Теперь входы в
●
Функции типов (
●
Аргумент
Новые фичи
● Пакет теперь умеет в многопоточность и батчинг:
●
●
Эти функции пока экспериментальные — возможно, интерфейс будет дорабатываться.
Работа с файлами:
●
Работа с моделями:
Теперь можно получить список доступных моделей у разных провайдеров:
●
●
●
●
●
●
Возвращается data.frame с id и ценой за токены.
Генерация промптов:
●
●
Унифицированные параметры моделей:
●
Учёт стоимости:
●
Поддержка новых провайдеров:
Добавлены клиенты для:
● Hugging Face:
● Mistral:
● Portkey:
Переименования функций (с поддержкой старых имён):
●
●
●
Также обновлены дефолтные модели:
●
●
Фичи для разработчиков:
●
●
●
● Поддержка хуков
Работа с инструментами:
●
●
Новое в ContentToolResult:
● Можно возвращать прямо из
● Теперь есть extra, request, и error поля.
Мелкие улучшения и фиксы:
● Установлен кастомный User-Agent и увеличен timeout до 5 минут.
●
● Новые способы аутентификации в Gemini и Vertex через
●
Сам пока не обновлялся, только увидел новость о релизе.
#новости_и_релизы_по_R
3 предыдущие поста в канале так или иначе были связаны с пакетом
ellmer
, и вот 17 мая на CRAN вышла его новая версия. Разбираю всё по порядку:Breaking changes
● Изменения в преобразовании JSON → R
Теперь входы в
tool()
всегда автоматически преобразуются в стандартные структуры R (list, data.frame и т.д.). Если нужно сохранить оригинальные объекты, можно явно отключить это поведение с convert = FALSE
.●
NULL → NA
Функции типов (
type_boolean()
, type_integer()
и т.д.) теперь преобразуют NULL
в NA
, что делает работу с необязательными параметрами более предсказуемой.●
chat_
функции теперь без turn
Аргумент
turn
удалён. Заменой служит Chat$set_turns()
. Также Chat$tokens()
переименован в Chat$get_tokens()
и теперь возвращает корректно выровненные токены в виде data.frame.Новые фичи
● Пакет теперь умеет в многопоточность и батчинг:
●
batch_chat()
и batch_chat_structured()
— отправка батчей в OpenAI и Anthropic. Ответ может прийти в течение 24 часов, но стоит в 2 раза дешевле.●
parallel_chat()
и parallel_chat_structured()
— параллельные запросы, быстрее, но без экономии в цене.Эти функции пока экспериментальные — возможно, интерфейс будет дорабатываться.
Работа с файлами:
●
google_upload()
— загрузка PDF, видео и других файлов для Gemini или Vertex AI.Работа с моделями:
Теперь можно получить список доступных моделей у разных провайдеров:
●
models_google_gemini()
●
models_openai()
●
models_anthropic()
●
models_aws_bedrock()
●
models_ollama()
●
models_vllm()
Возвращается data.frame с id и ценой за токены.
Генерация промптов:
●
interpolate()
теперь векторизован: можно генерировать много промптов сразу.●
interpolate_package()
— генерация из шаблонов внутри inst/prompts/
.Унифицированные параметры моделей:
●
chat_anthropic()
, chat_openai()
, chat_gemini()
, chat_azure()
теперь принимают аргумент params, в который можно передать temperature, seed и пр. через params()
.Учёт стоимости:
●
Chat$get_cost()
, tokens_usage()
, и сам принт объекта Chat теперь показывают оценку стоимости (в токенах и долларах).Поддержка новых провайдеров:
Добавлены клиенты для:
● Hugging Face:
chat_huggingface()
● Mistral:
chat_mistral()
● Portkey:
chat_portkey()
+ models_portkey()
Переименования функций (с поддержкой старых имён):
●
chat_azure()
→ chat_azure_openai()
●
chat_bedrock()
→ chat_aws_bedrock()
●
chat_gemini()
→ chat_google_gemini()
Также обновлены дефолтные модели:
●
chat_anthropic()
теперь использует Sonnet 3.7●
chat_openai()
— GPT-4.1Фичи для разработчиков:
●
Chat$get_provider()
— доступ к провайдеру.●
Chat$chat_async()
и Chat$stream_async()
поддерживают tool_mode = "sequential"/"concurrent"
— влияет на последовательность вызова инструментов.●
Chat$stream()
и stream_async()
теперь могут стримить ContentToolRequest/Result
.● Поддержка хуков
Chat$on_tool_request()
и on_tool_result()
— можно логировать или вмешиваться в обработку инструментов.Работа с инструментами:
●
tool()
теперь поддерживает .annotations
(через tool_annotations()
), описывающие инструменты.●
tool_reject()
— отказ от вызова инструмента с объяснением, почему.Новое в ContentToolResult:
● Можно возвращать прямо из
tool()
.● Теперь есть extra, request, и error поля.
Мелкие улучшения и фиксы:
● Установлен кастомный User-Agent и увеличен timeout до 5 минут.
●
chat_anthropic()
теперь поддерживает content_image_url()
и новый тип thinking.● Новые способы аутентификации в Gemini и Vertex через
GEMINI_API_KEY
и Google ADC.●
chat_anthropic(max_tokens = )
теперь deprecated — используйте params =
.Сам пока не обновлялся, только увидел новость о релизе.
#новости_и_релизы_по_R
Анализ GitHub репозиториев с помощью AI
Попался на глаза ещё один интересный проект Хедли - GitAI. Это свежий инструмент в экосистеме R, предназначенный для извлечения знаний из Git-репозиториев с помощью больших языковых моделей (LLM).
GitAI — это R-пакет, который позволяет:
● Сканировать один или несколько Git-репозиториев (GitHub или GitLab).
● Извлекать содержимое определённых файлов, например, README.md.
● Обрабатывать это содержимое с помощью LLM, чтобы получить краткие описания или ответы на конкретные вопросы.
● Сохранять результаты в векторную базу данных для последующего семантического поиска или использования в Retrieval Augmented Generation (RAG) сценариях.
Пример использования
Вот пошаговый пример того, как использовать GitAI для анализа нескольких репозиториев:
Для работы кода необходимо указать через переменные среды API токены для работы с GitHub и Gemini (или другой LLM моделью).
Результат
Основные функции:
●
●
●
●
●
●
●
●
#заметки_по_R
Попался на глаза ещё один интересный проект Хедли - GitAI. Это свежий инструмент в экосистеме R, предназначенный для извлечения знаний из Git-репозиториев с помощью больших языковых моделей (LLM).
GitAI — это R-пакет, который позволяет:
● Сканировать один или несколько Git-репозиториев (GitHub или GitLab).
● Извлекать содержимое определённых файлов, например, README.md.
● Обрабатывать это содержимое с помощью LLM, чтобы получить краткие описания или ответы на конкретные вопросы.
● Сохранять результаты в векторную базу данных для последующего семантического поиска или использования в Retrieval Augmented Generation (RAG) сценариях.
Пример использования
Вот пошаговый пример того, как использовать GitAI для анализа нескольких репозиториев:
Для работы кода необходимо указать через переменные среды API токены для работы с GitHub и Gemini (или другой LLM моделью).
Sys.setenv('GOOGLE_API_KEY' = 'ваш токен для GEMINI API')
Sys.setenv("GITHUB_PAT" = 'ваш персональный GITHUB токен')
library(GitAI)
# Устанавливаем таймаут и отключаем подробный вывод
options(ellmer_timeout_s = 120)
verbose_off()
# Инициализируем проект
my_project <- initialize_project("fascinating_project") |>
set_github_repos(
repos = c(
"r-world-devs/GitStats",
"r-world-devs/GitAI",
"openpharma/DataFakeR"
)
) |>
add_files(files = "README.md") |>
set_llm('gemini') |>
set_prompt("Напиши краткое изложение проекта в одном предложении на основе предоставленных данных.")
# Обрабатываем репозитории
results <- process_repos(my_project)
# Выводим результаты
purrr::walk(results, function(result) {
cat(stringr::str_wrap(result$text, width = 80), "\n\n")
})
Результат
Проект `GitStats` предоставляет унифицированный способ получения данных
из GitHub и GitLab, таких как организации, репозитории, коммиты, задачи,
пользователи, журналы выпусков, структура файлов, содержимое текстовых файлов и
использование R-пакетов, а также предоставляет базовую статистику по коммитам и
задачам.
Проект GitAI предоставляет фреймворк на R для извлечения и анализа знаний
из Git-репозиториев с использованием ИИ и больших языковых моделей, чтобы
автоматизировать обзор и улучшить повторное использование кода и информации.
DataFakeR - это R-пакет, предназначенный для генерации фейковых данных,
сохраняющих определенные характеристики оригинальных данных, с возможностью
настройки схемы данных через YAML-файлы и определения пользовательских методов
симуляции.
Основные функции:
●
initialize_project(name)
: Инициализирует новый проект GitAI.●
set_github_repos(repos)
: Устанавливает список GitHub-репозиториев для анализа.●
add_files(files)
: Указывает, какие файлы из репозиториев нужно анализировать.●
set_llm(...)
: Настраивает использование LLM для обработки содержимого.●
set_prompt(prompt)
: Устанавливает запрос, который будет передан модели.●
process_repos(project)
: Запускает процесс анализа репозиториев.●
set_database(...)
: Настраивает векторную базу данных для хранения результатов.●
find_records(...)
: Позволяет выполнять поиск по сохранённым результатам.#заметки_по_R