{"id":38544430,"url":"https://github.com/vic-cheung/rpy-bridge","last_synced_at":"2026-01-17T07:16:55.083Z","repository":{"id":325207676,"uuid":"1100252917","full_name":"vic-cheung/rpy-bridge","owner":"vic-cheung","description":"Python-R interoperability layer for environment management, type-safe conversions, data normalization, safe function execution, and supporting recursive R object unpacking.","archived":false,"fork":false,"pushed_at":"2025-12-15T21:58:43.000Z","size":5943,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-16T10:27:02.813Z","etag":null,"topics":["bioinformatics","bridge","interoperability","interoperability-layer","python","python-bridge","r","rpy2","statistics"],"latest_commit_sha":null,"homepage":"https://rpy-bridge.readthedocs.io/en/stable/usage.html","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vic-cheung.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-20T03:25:19.000Z","updated_at":"2025-12-15T21:58:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vic-cheung/rpy-bridge","commit_stats":null,"previous_names":["vic-cheung/rpy-bridge"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/vic-cheung/rpy-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic-cheung%2Frpy-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic-cheung%2Frpy-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic-cheung%2Frpy-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic-cheung%2Frpy-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vic-cheung","download_url":"https://codeload.github.com/vic-cheung/rpy-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic-cheung%2Frpy-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28503362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bioinformatics","bridge","interoperability","interoperability-layer","python","python-bridge","r","rpy2","statistics"],"created_at":"2026-01-17T07:16:54.426Z","updated_at":"2026-01-17T07:16:55.069Z","avatar_url":"https://github.com/vic-cheung.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rpy-bridge\n\n**rpy-bridge** is a Python-controlled **R execution orchestrator** (not a thin\nrpy2 wrapper). It delivers deterministic, headless-safe R startup; project-root\ninference; out-of-tree `renv` activation; isolated script namespaces; and robust\nPython↔R conversions with dtype/NA normalization. Use it when you need\nreproducible R execution from Python in production pipelines and CI.\n\n**Latest release:** [`rpy-bridge` on PyPI](https://pypi.org/project/rpy-bridge/)\n\n---\n\n## What this is (and is not)\n\nrpy-bridge **is not a thin rpy2 wrapper**. Key differences:\n\n- Infers R project roots via markers (`.git`, `.Rproj`, `renv.lock`, `DESCRIPTION`, `.here`)\n- Activates `renv` even when it lives outside the calling directory\n- Executes from the inferred project root so relative paths behave as R expects\n- Runs headless by default (no GUI probing), isolates scripts from `globalenv()`\n- Normalizes return values for Python (NAs, dtypes, data.frames) and offers comparison helpers\n\n---\n\n## Quickstart\n\nCall a package function (no scripts):\n\n```python\nfrom rpy_bridge import RFunctionCaller\n\nrfc = RFunctionCaller()\nsamples = rfc.call(\"stats::rnorm\", 5, mean=0, sd=1)\nmedian_val = rfc.call(\"stats::median\", samples)\n```\n\nCall a function from a local script with `renv` (out-of-tree allowed):\n\n```python\nfrom pathlib import Path\nfrom rpy_bridge import RFunctionCaller\n\nproject_dir = Path(\"/path/to/your-r-project\")\nscript = project_dir / \"scripts\" / \"example.R\"\n\nrfc = RFunctionCaller(path_to_renv=project_dir, scripts=script)\nresult = rfc.call(\"some_function\", 42, named_arg=\"value\")\n```\n\n## Core capabilities\n\n### 1. R execution orchestration\n\n- Embeds R via `rpy2` with deterministic startup behavior\n- Disables interactive and GUI-dependent hooks for headless execution\n- Loads R scripts into isolated namespaces (not `globalenv()`)\n\n### 2. Project root inference and path stability\n\n- Infers R project roots using markers such as:\n  `.git`, `.Rproj`, `renv.lock`, `DESCRIPTION`, `.here`\n- Executes R code from the inferred project root regardless of Python CWD\n- Preserves relative-path behavior expected by R scripts\n- Supports R code using `here::here()` or project-local data\n\n### 3. Out-of-tree `renv` activation\n\n- Activates `renv` projects located **outside** the calling Python directory\n- Sources `.Rprofile` and `.Renviron` to reproduce R startup semantics\n- Does not require R scripts and `renv` to live in the same directory\n\n### 4. Python ↔ R data conversion\n\n- Converts Python scalars, lists, dicts, and pandas objects into R equivalents\n- Converts R vectors, lists, and data.frames back into Python-native types\n- Handles nested structures, missing values, and mixed types robustly\n\n### 5. Data normalization and diagnostics\n\n- Post-processes R data.frames to fix dtype, timezone, and NA semantics\n- Normalizes column types for reliable Python-side comparison\n- Supports structured mismatch diagnostics between Python and R data\n\n### 6. Function invocation across scripts and packages\n\n- Calls functions defined in sourced R scripts, base R, or installed packages\n- Supports qualified function names (e.g. `stats::median`)\n- Executes functions within the active project and library context\n\n---\n\n## Calling base R functions and managing packages\n\nIn addition to sourcing local R scripts, rpy-bridge supports calling functions\nfrom base R and installed packages directly from Python.\n\nCurrent support includes:\n\n- Calling base R functions without a local R script\n- Executing functions from installed R packages within the active environment\n\nPlanned extensions (roadmap):\n\n- Programmatic installation of R packages into the active `renv` or system\n  environment when explicitly enabled\n- Declarative package requirements at the Python call site\n- Safe, opt-in package installation for CI and ephemeral environments\n\nPackage installation is intentionally **not automatic by default** to preserve\nreproducibility and avoid side effects during execution.\n\n---\n\n## Installation\n\n### Prerequisites\n\n- System R installed and available on `PATH`\n- Python 3.11+ (tested on 3.11–3.12)\n\n### From PyPI\n\nInstall rpy-bridge with rpy2 for full R support:\n\n```bash\npython3 -m pip install rpy-bridge rpy2\n```\n\nUsing `uv`:\n\n```bash\nuv add rpy-bridge rpy2\n```\n\n### Development install\n\n```bash\npython3 -m pip install -e .\n```\n\nor:\n\n```bash\nuv sync\n```\n\n### Required Python dependencies\n\n- `rpy2`\n- `pandas`\n- `numpy`\n\n---\n\n## Usage\n\nSee Quickstart above and examples in `examples/basic_usage.py`.\n\n---\n\n## Round-trip Python ↔ R behavior\n\nrpy-bridge attempts to convert Python objects to R and back. Most objects used in\nscientific and ML pipelines round-trip cleanly, but some heterogeneous Python\nstructures may be wrapped or slightly altered due to differences in R’s type\nsystem.\n\n| Python type                                    | Round-trip fidelity | Notes                                                                 |\n| ---------------------------------------------- | ------------------- | --------------------------------------------------------------------- |\n| `int`, `float`, `bool`, `str`                  | High                | Scalars convert directly                                              |\n| Homogeneous `list` of numbers/strings          | High                | Converted to atomic R vectors                                         |\n| Nested homogeneous lists                       | High                | Converted to nested R lists                                           |\n| `pandas.DataFrame` / `pd.Series`               | High                | Converted to `data.frame` and normalized on return                    |\n| Mixed-type `list` or `dict`                    | Partial             | May be wrapped in single-element vectors                              |\n| `None` / `pd.NA`                               | High                | Converted to R `NULL`                                                 |\n\n---\n\n## R setup helpers\n\nHelper scripts are provided in `examples/r-deps/` to prepare R environments.\n\n- Install system R dependencies (macOS / Homebrew):\n\n```bash\nbash examples/r-deps/install_r_dev_deps_homebrew.sh\n```\n\n- Initialize an `renv` project:\n\n```r\nsource(\"examples/r-deps/setup_env.R\")\n```\n\n- Restore the environment on a new machine:\n\n```r\nrenv::restore()\n```\n\n---\n\n## Who this is for\n\nrpy-bridge is designed for:\n\n- Python-first pipelines that rely on mature R code\n- Teams where R logic must remain authoritative\n- CI or production systems that cannot rely on interactive R sessions\n- Multi-repo or multi-directory projects with non-trivial filesystem layouts\n\nIt is **not** intended as a convenience wrapper for exploratory R usage.\n\n---\n\n## Licensing\n\n- rpy-bridge is released under the MIT License © 2025 Victoria Cheung\n- Depends on [`rpy2`](https://rpy2.github.io), licensed under the GNU GPL (v2 or later)\n\n---\n\n## Acknowledgements\n\nThis package was spun out of internal tooling I wrote at Revolution Medicines.\nThanks to the team there for supporting its open-source release.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic-cheung%2Frpy-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvic-cheung%2Frpy-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic-cheung%2Frpy-bridge/lists"}