Introduction to Rparadox

Introduction

Rparadox provides a simple and efficient way to read data from Paradox database files (.db) directly into R as modern tibble data frames. It uses the underlying pxlib C library to handle the low-level file format details and provides a clean, user-friendly R interface.

This package is designed to “just work” for the most common use case: extracting the full dataset from a Paradox table, including its associated BLOB/memo file (.mb).

Features

  • Direct Reading: Reads Paradox .db files without needing database drivers or external software.
  • Tibble Output: Returns data in the tibble format, fully compatible with the Tidyverse ecosystem.
  • Automatic BLOB Handling: Automatically detects, attaches, and reads data from associated memo/BLOB (.mb) files.
  • Encryption Support: Supports reading password-protected Paradox files.
  • Character Encoding Control: Automatically handles character encoding conversion to UTF-8 and allows manual override of the source encoding for files with incorrect headers.
  • Type Conversion: Correctly maps Paradox data types to their corresponding R types, including Date, Time (hms), Timestamp (POSIXct), Logical, Integer, Numeric, and binary blob objects.

Installation

# stable version from CRAN
install.packages("Rparadox")

You can install the development version from GitHub:

# install.packages("devtools")
devtools::install_github("celebithil/Rparadox")

Basic Usage: read_paradox()

The easiest way to read a Paradox file is with the high-level read_paradox() function. It handles opening the file, reading the data, and closing the connection in a single step.

# Get the path to an example database included with the package
db_path <- system.file("extdata", "biolife.db", package = "Rparadox")

# Read the data directly into a tibble
# This automatically finds 'biolife.mb' and handles data types.
biolife_data <- read_paradox(db_path)

# View the data
print(biolife_data)
#> # A tibble: 28 × 8
#>    `Species No` Category      Common_Name `Species Name` `Length (cm)` Length_In
#>           <dbl> <chr>         <chr>       <chr>                  <dbl>     <dbl>
#>  1        90020 Triggerfish   Clown Trig… Ballistoides …            50     19.7 
#>  2        90030 Snapper       Red Emperor Lutjanus sebae            60     23.6 
#>  3        90050 Wrasse        Giant Maor… Cheilinus und…           229     90.2 
#>  4        90070 Angelfish     Blue Angel… Pomacanthus n…            30     11.8 
#>  5        90080 Cod           Lunartail … Variola louti             80     31.5 
#>  6        90090 Scorpionfish  Firefish    Pterois volit…            38     15.0 
#>  7        90100 Butterflyfish Ornate But… Chaetodon Orn…            19      7.48
#>  8        90110 Shark         Swell Shark Cephaloscylli…           102     40.2 
#>  9        90120 Ray           Bat Ray     Myliobatis ca…            56     22.0 
#> 10        90130 Eel           California… Gymnothorax m…           150     59.1 
#> # ℹ 18 more rows
#> # ℹ 2 more variables: Notes <chr>, Graphic <blob>
# Plot raw image data
library(magick)
#> Linking to ImageMagick 7.1.2.18
#> Enabled features: fontconfig, freetype, fftw, heic, lcms, raw, webp, x11
#> Disabled features: cairo, ghostscript, pango, rsvg
#> Using 3 threads

as.raw(biolife_data$Graphic[[1]]) |> image_read() |> plot()

Reading Encrypted Files

If your Paradox file is password-protected, provide the password using the password argument:

library(Rparadox)
# Read a password-protected file
secure_data <- read_paradox("path/to/encrypted.db", password = "secret_password")

If the file is encrypted and no password (or an incorrect one) is provided, the function will stop with an error message.

Handling Character Encodings

For legacy files with incorrect encoding information in the header, you can specify the correct encoding manually with the encoding parameter:

library(Rparadox)
# This tells the package to interpret the source data as CP866
data <- read_paradox("path/to/your/file.db", encoding = "cp866")

This ensures that all text fields are correctly converted to UTF-8 in the final tibble.

Advanced Usage: Metadata and Manual Control

If you need more control — for instance, to inspect metadata before committing to reading a large dataset — you can use the lower-level functions.

The workflow is:

  1. pxlib_open_file() to get a file handle.
  2. pxlib_metadata() to inspect metadata (optional).
  3. pxlib_get_data() to read the data.
  4. pxlib_close_file() to release the connection.
db_path <- system.file("extdata", "biolife.db", package = "Rparadox")

# Open the file and get a handle
pxdoc <- pxlib_open_file(db_path)

if (!is.null(pxdoc)) {
  # Get metadata without reading all the data
  metadata <- pxlib_metadata(pxdoc)

  # Metadata includes human-readable field types and detected encoding
  cat("Encoding:", metadata$encoding, "\n")
  cat("Number of records:", metadata$num_records, "\n")
  print(head(metadata$fields))

  # Read the actual data
  data_table <- pxlib_get_data(pxdoc)

  # Always close the file when you're done
  pxlib_close_file(pxdoc)

  print(data_table)
}
#> Encoding: CP437 
#> Number of records: 28 
#>           name   type size
#> 1   Species No Number    8
#> 2     Category  Alpha   15
#> 3  Common_Name  Alpha   30
#> 4 Species Name  Alpha   40
#> 5  Length (cm) Number    8
#> 6    Length_In Number    8
#> # A tibble: 28 × 8
#>    `Species No` Category      Common_Name `Species Name` `Length (cm)` Length_In
#>           <dbl> <chr>         <chr>       <chr>                  <dbl>     <dbl>
#>  1        90020 Triggerfish   Clown Trig… Ballistoides …            50     19.7 
#>  2        90030 Snapper       Red Emperor Lutjanus sebae            60     23.6 
#>  3        90050 Wrasse        Giant Maor… Cheilinus und…           229     90.2 
#>  4        90070 Angelfish     Blue Angel… Pomacanthus n…            30     11.8 
#>  5        90080 Cod           Lunartail … Variola louti             80     31.5 
#>  6        90090 Scorpionfish  Firefish    Pterois volit…            38     15.0 
#>  7        90100 Butterflyfish Ornate But… Chaetodon Orn…            19      7.48
#>  8        90110 Shark         Swell Shark Cephaloscylli…           102     40.2 
#>  9        90120 Ray           Bat Ray     Myliobatis ca…            56     22.0 
#> 10        90130 Eel           California… Gymnothorax m…           150     59.1 
#> # ℹ 18 more rows
#> # ℹ 2 more variables: Notes <chr>, Graphic <blob>