Skip to content

r_bridge

Call a persistent R interpreter from Python — with a Pythonic API, full numpy/pandas support, and zero ceremony.

from r_bridge import RBridge

with RBridge() as r:
    r.x = [1, 2, 3, 4, 5]
    print(r.mean(r.x))   # 3.0

Why r_bridge?

Python and R each have unique strengths. Rather than rewriting R code or shelling out to Rscript for every call, r_bridge keeps a single R process alive for the lifetime of your session. Calls are fast, state is shared, and the API feels natural on both sides.

  • 🚀 No subprocess-per-call overhead — R starts once, stays running
  • 🔄 Automatic type conversion — Python lists, numpy arrays, pandas DataFrames and datetimes all round-trip transparently
  • 🔒 Thread-safe — a single lock serialises concurrent calls
  • 🛡️ Robust — a sentinel-prefixed protocol means stray cat() output never corrupts the stream

How it works

r_bridge spawns Rscript once and communicates over stdin/stdout using line-delimited JSON with a __RBRIDGE__: sentinel prefix on every protocol line.

🐍 Python ──► __RBRIDGE__:{"id":"…","op":"call_func","payload":{…}}
📊 R      ──► __RBRIDGE__:{"id":"…","status":"ok","payload":{…},"warnings":[]}

A dedicated daemon thread drains R's stderr continuously to prevent pipe-buffer deadlocks. A single threading.Lock serialises concurrent Python calls.