We use cookies and other tracking technologies to improve your browsing experience on our website, to show you personalized content and targeted ads, to analyze our website traffic, and to understand where our visitors are coming from.
Warning - This site is under development. Some features may not work as expected.
duckspatial v0.9.0
R
spatial
duckspatial
New duckspatial version. A major step towards v1.0.0
Author
Adrián Cidre
Published
January 10, 2026
1 Introduction
I’m exited to announce the release of {duckspatial} v0.9.0 (Cidre González, Pereira, and Kotov 2026) , now available ON CRAN! This new version brings a major evolution of the package, with substantial changes that make the way towards version 1.0.0.
2 What is duckspatial?
For those new to the package, {duckspatial} brings the power of DuckDB’s spatial extension to R. It provides fast and memory-efficient functions to analyze and manipulate large spatial vector datasets while maintaining full compatibility with R’s spatial ecosystem, especially the {sf} package (Pebesma and Bivand 2023).
The package is designed for situations where:
You’re working with large spatial datasets
You need to speed up spatial analysis at scale
Your data doesn’t fit in memory
3 Major changes in 0.9.0
If you’ve used {duckspatial} before, you might ask why did we jump from version 0.2.0 to version 0.9.0, instead of 0.3.0 or 1.0.0. Well, this new release brings substantial changes, some of them might have incompatibilities with the previous version. However, we are reserving the v1.0.0 for the next release that we are working in, which will bring fantastic news, such as lazy duckspatial tables, and native support of Coordinates Reference Systems (CRS) within DuckDB (see this issue for a reference). In this sense, to we decided that moving to 0.3.0 wasn’t enough for the big changes this versions brings, and we think version 1.0.0 should be released with the previously mentioned roadmap. So now that we know why this is v0.9.0, let’s dive into the major changes.
3.1 Simplified connection handling
The biggest change in this release is how the connections are handled. The conn argument now defaults to NULL in every spatial operation (e.g. ddbs_centroid, ddbs_filter, ddbs_area, …), and it’s no longer a mandatory argument. This means that the package will handle internally the connection if the user prefer to work with {sf} objects instead of DuckDB tables, making the package more user friendly. The next examples show how to calculate the centroid using a connection, or without using a connection.
NOTE: The first time you use one function from {duckspatial}, it will run internally ddbs_install() and ddbs_load() to set up the spatial extension, and it will take slightly longer. After the first time, everything will go faster.
## load packageslibrary(duckspatial)library(sf)## load Argentina boundaries as sfargentina_sf<-read_sf(system.file("spatial/argentina.geojson", package ="duckspatial"))## get centroidargentina_centroid_sf<-ddbs_centroid(argentina_sf)argentina_centroid_sf
Simple feature collection with 1 feature and 6 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -65.14851 ymin: -35.20212 xmax: -65.14851 ymax: -35.20212
Geodetic CRS: WGS 84
CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME FID date
1 AR Argentina ARG Argentina AR 2021-01-01
geometry
1 POINT (-65.14851 -35.20212)
## load packageslibrary(duckspatial)library(sf)## create a connection (in memory)## NOTE: ddbs_create_conn() is a wrapper of dbConnect(), ddbs_install(), and ddbs_load()conn<-ddbs_create_conn()## load Argentina boundaries as sfargentina_sf<-read_sf(system.file("spatial/argentina.geojson", package ="duckspatial"))## get centroidargentina_centroid_sf<-ddbs_centroid(argentina_sf, conn)argentina_centroid_sf
Simple feature collection with 1 feature and 6 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -65.14851 ymin: -35.20212 xmax: -65.14851 ymax: -35.20212
Geodetic CRS: WGS 84
CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME FID date
1 AR Argentina ARG Argentina AR 2021-01-01
geometry
1 POINT (-65.14851 -35.20212)
This change makes {duckspatial} feel more natural for {sf} users while still offering the flexibility to work with existing DuckDB connections when needed.
3.2 Flexible Input/Output
All spatial functions now support four workflows:
Input sf → Output sf
Input sf → Output DuckDB table
Input DuckDB table → Output sf
Input DuckDB table → Output DuckDB table
This flexibility lets you choose the right approach for your data size and workflow. Note that working inside DuckDB without pulling the data into R’s memory will be much more efficient, but it will be different than an {sf} workflow.
## write data into the connectionddbs_write_vector(conn, argentina_centroid_sf, name ="argentina")## input duckdb table, output sfargentina_centroid_sf<-ddbs_centroid("argentina", conn)
ddbs_centroid(argentina_sf, conn, name ="argentina_centroid")
ddbs_centroid("argentina", conn, name ="argentina_centroid", overwrite =TRUE)
3.3 Performance Improvements
Two key optimizations make this release significantly faster:
Faster table creation: ddbs_write_vector() now supports temp = TRUE to create temporary views, which is much faster than creating permanent tables.
The crs and crs_column arguments are now deprecated and will be removed in version 1.0.0. This change aligns with native CRS support coming to DuckDB v1.5.0 (expected February 2026). The package will handle coordinate reference systems more seamlessly once DuckDB’s native support is available.
4 New Features
This release adds a substantial number of new spatial functions, greatly expanding what you can do with {duckspatial}. Particularly, it brings more than 30 new functions!! 🚀
All functions now have a quiet parameter to suppress messages
Fixed issue where columns with dots in their names would cause failures
Improved ddbs_filter() to avoid duplicates when geometries match multiple predicates
Added comprehensive vignettes for getting started
6 Looking Ahead to 1.0.0
Version 0.9.0 sets the stage for the 1.0.0 release, which will bring additional substantial changes. The upcoming release will fully integrate DuckDB’s native CRS support and lazy duckspatial tables.
7 Acknowledgments
This release wouldn’t be possible without the incredible work of many people.
First and foremost, my deepest thanks to the DuckDB team for building such a powerful and elegant analytical engine. Their commitment to performance, correctness, and developer experience has created a foundation that makes tools like {duckspatial} possible.
Special recognition goes to the developers of the DuckDB Spatial Extension, the engine that powers everything in {duckspatial}. Their unvaluable work on spatial operations, format support, and performance optimization is what makes this package capable of handling large-scale spatial analysis efficiently.
Most importantly, this release represents a true collaborative effort. Rafael Pereira and Egor Kotov have been fundamental in shaping duckspatial’s new design and implementation. Their ideas, code contributions, and thoughtful feedback have shaped this package far beyond what I could have achieved alone. This is a shared accomplishment.
Finally, thank you to the broader R spatial community for building the ecosystem that {duckspatial} integrates with, and to everyone who has tested early versions, reported issues, or provided feedback.
8 References
Cidre González, Adrián, Rafael H. M. Pereira, and Egor Kotov. 2026. “Duckspatial: R Interface to ’DuckDB’ Database with Spatial Extension.”https://github.com/Cidree/duckspatial.