R API
Установка
duckdb: R API
API DuckDB для R можно установить с помощью следующей команды:
install.packages("duckdb") Подробную информацию смотрите на странице установки.
duckplyr: API dplyr
DuckDB предоставляет совместимый с dplyr API через пакет duckplyr. Его можно установить с помощью install.packages("duckplyr"). Подробности см. в документации duckplyr.
Справочное руководство
Справочное руководство по API DuckDB для R доступно по адресу R.duckdb.org.
Базовое использование API
Стандартный API DuckDB для R реализует интерфейс DBI для R. Если вы еще не знакомы с DBI, ознакомьтесь со страницей использования DBI для введения.
Инициализация и завершение работы
Для использования DuckDB необходимо сначала создать объект подключения, представляющий базу данных. Объект подключения принимает в качестве параметра файл базы данных для чтения и записи. Если файла базы данных не существует, он будет создан (расширение файла может быть .db, .duckdb, или любым другим). Специальное значение :memory: (по умолчанию) можно использовать для создания базы данных в памяти. Обратите внимание, что для базы данных в памяти данные не сохраняются на диск (т. е. все данные будут потеряны при выходе из процесса R). Если вы хотите подключиться к существующей базе данных в режиме только для чтения, установите флаг read_only в значение TRUE. Режим только для чтения требуется, если несколько процессов R хотят одновременно получить доступ к одному файлу базы данных.
library("duckdb")
# to start an in-memory database
con <- dbConnect(duckdb())
# or
con <- dbConnect(duckdb(), dbdir = ":memory:")
# to use a database file (not shared between processes)
con <- dbConnect(duckdb(), dbdir = "my-db.duckdb", read_only = FALSE)
# to use a database file (shared between processes)
con <- dbConnect(duckdb(), dbdir = "my-db.duckdb", read_only = TRUE) Подключения закрываются неявно, когда они выходят из области видимости или если они явным образом закрываются с помощью dbDisconnect(). Чтобы завершить работу экземпляра базы данных, связанного с подключением, используйте dbDisconnect(con, shutdown = TRUE)
Запросы
DuckDB поддерживает стандартные методы DBI для отправки запросов и получения наборов результатов. dbExecute() предназначен для запросов, где не ожидаются результаты, такие как CREATE TABLE или UPDATE и т. д., а dbGetQuery() предназначен для использования для запросов, которые производят результаты (например, SELECT). Ниже приведен пример.
# create a table
dbExecute(con, "CREATE TABLE items (item VARCHAR, value DECIMAL(10, 2), count INTEGER)")
# insert two items into the table
dbExecute(con, "INSERT INTO items VALUES ('jeans', 20.0, 1), ('hammer', 42.2, 2)")
# retrieve the items again
res <- dbGetQuery(con, "SELECT * FROM items")
print(res)
# item value count
# 1 jeans 20.0 1
# 2 hammer 42.2 2 DuckDB также поддерживает подготовленные запросы в API R с помощью методов dbExecute и dbGetQuery. Вот пример:
# prepared statement parameters are given as a list
dbExecute(con, "INSERT INTO items VALUES (?, ?, ?)", list('laptop', 2000, 1))
# if you want to reuse a prepared statement multiple times, use dbSendStatement() and dbBind()
stmt <- dbSendStatement(con, "INSERT INTO items VALUES (?, ?, ?)")
dbBind(stmt, list('iphone', 300, 2))
dbBind(stmt, list('android', 3.5, 1))
dbClearResult(stmt)
# query the database using a prepared statement
res <- dbGetQuery(con, "SELECT item FROM items WHERE value > ?", list(400))
print(res)
# item
# 1 laptop Предупреждение Не используйте подготовленные запросы для вставки больших объемов данных в DuckDB. Смотрите ниже для лучших вариантов.
Эффективная передача данных
Для записи кадра данных R в DuckDB используйте стандартную функцию DBI dbWriteTable(). Это создает таблицу в DuckDB и заполняет ее содержимым кадра данных. Например:
dbWriteTable(con, "iris_table", iris) res <- dbGetQuery(con, "SELECT * FROM iris_table LIMIT 1") print(res) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # 1 5.1 3.5 1.4 0.2 setosa
Также можно «зарегистрировать» кадр данных R как виртуальную таблицу, аналогичную SQL VIEW. Это не фактически передает данные в DuckDB пока. Ниже приведен пример:
duckdb_register(con, "iris_view", iris) res <- dbGetQuery(con, "SELECT * FROM iris_view LIMIT 1") print(res) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # 1 5.1 3.5 1.4 0.2 setosa
DuckDB сохраняет ссылку на кадр данных R после регистрации. Это предотвращает сборку мусора кадра данных. Ссылка удаляется при закрытии подключения, но также может быть удалена вручную с помощью метода
duckdb_unregister().
Также обратитесь к документации по импорту данных для получения дополнительных вариантов эффективного импорта данных.
dbplyr
DuckDB также хорошо работает с пакетами dbplyr / dplyr для программирования построения запросов из R. Вот пример:
library("duckdb")
library("dplyr")
con <- dbConnect(duckdb())
duckdb_register(con, "flights", nycflights13::flights)
tbl(con, "flights") |>
group_by(dest) |>
summarise(delay = mean(dep_time, na.rm = TRUE)) |>
collect() При использовании dbplyr файлы CSV и Parquet можно читать с помощью функции dplyr::tbl.
# Establish a CSV for the sake of this example write.csv(mtcars, "mtcars.csv") # Summarize the dataset in DuckDB to avoid reading the entire CSV into R's memory tbl(con, "mtcars.csv") |> group_by(cyl) |> summarise(across(disp:wt, .fns = mean)) |> collect()
# Establish a set of Parquet files
dbExecute(con, "COPY flights TO 'dataset' (FORMAT PARQUET, PARTITION_BY (year, month))")
# Summarize the dataset in DuckDB to avoid reading 12 Parquet files into R's memory
tbl(con, "read_parquet('dataset/**/*.parquet', hive_partitioning = true)") |>
filter(month == "3") |>
summarise(delay = mean(dep_time, na.rm = TRUE)) |>
collect() Ограничение памяти
Вы можете использовать memory_limit опцию конфигурации для ограничения использования памяти DuckDB, например:
SET memory_limit = '2GB';
Обратите внимание, что это ограничение применяется только к памяти, которую использует DuckDB, и не влияет на использование памяти других библиотек R. Таким образом, общее использование памяти процессом R может быть выше, чем настроенное memory_limit.
Отладка
Предупреждение при установке на macOS
При установке DuckDB на macOS может появиться предупреждение unable to load shared object '.../R_X11.so':
Warning message: In doTryCatch(return(expr), name, parentenv, handler) : unable to load shared object '/Library/Frameworks/R.framework/Resources/modules//R_X11.so': dlopen(/Library/Frameworks/R.framework/Resources/modules//R_X11.so, 0x0006): Library not loaded: /opt/X11/lib/libSM.6.dylib Referenced from: <31EADEB5-0A17-3546-9944-9B3747071FE8> /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/modules/R_X11.so Reason: tried: '/opt/X11/lib/libSM.6.dylib' (no such file) ... > ')
Обратите внимание, что это всего лишь предупреждение, поэтому проще всего его игнорировать. В качестве альтернативы вы можете установить DuckDB из R-universe:
install.packages("duckdb", repos = c("https://duckdb.r-universe.dev", "https://cloud.r-project.org")) Вы также можете установить необязательную зависимость xquartz через Homebrew.
© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/api/r.html