Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Polyester

Polyester makes it possible to use R from Python by running R in a background process and communicating through a lightweight message protocol.

The goal is simplicity and reliability — especially on Windows — while keeping the design extensible to other languages in the future.


Quick Example

from polyester import RInterpreter

# Start an R interpreter
R = RInterpreter(path=r"C:\Program Files\R\R-4.5.2\bin\Rscript.exe")

# Access an R module (namespace)
rbase = R.module("base")

# Simple calculations
x = R.eval("sin(100)")
y = rbase.cos(100)

# Get results in python
print(R.get(x), R.get(y))

# Bring a dataframe from R to Python
iris_rdf = R.eval("iris")            # RemoteObject
iris_df = R.get(iris_rdf, "pandas")  # Python/pandas object
print(iris_df.head())

Core Concepts

Polyester revolves around a single concept: an interpreter.

An interpreter manages:

  • A background R process
  • A private remote environment
  • Communication over JSON Lines
  • Data exchange using Apache Arrow

Interpreter API

An interpreter supports the following operations:

Operation Parameters Returns Description
insert x: simple/dataframe RemoteObject Send Python data to R
get x: Remote simple/dataframe Retrieve data from R
R.objects.name name: str RemoteName (lazy) Reference a remote symbol
R.objects.name = value name: str, value: simple/Remote Assign remotely
eval code: str RemoteObject Evaluate R code
exec code: str Execute R code (no return value)
call f: Remote, *args, **kwargs RemoteObject Call a remote function

RemoteObject vs RemoteName

  • RemoteObject A concrete object that exists in the remote R environment. Automatically cleaned up when the Python object is deleted.

  • RemoteName A lazy reference to a symbol or expression in R. It may or may not exist until evaluated.

Example:

R.objects.x = 10
result = R.get(R.objects.x)   # 10

Data Exchange

DataFrames are transferred using Apache Arrow files for efficiency.

You can request a specific backend when retrieving:

df = R.get(iris_rdf, "pandas")

If no df_backend is provided, polars will be used.


Important Notes

Do not print to stdout from R.

Polyester uses stdout for protocol communication. Printing to stdout() inside R will corrupt the communication channel.

If you need logging inside R, use:

message("debug info")

or write to stderr().


Why Not Use rpy2?

rpy2 is a mature and powerful solution.

However:

  • rpy2 is currently difficult to use on Windows in many environments.
  • Polyester runs R as a subprocess and avoids tight binary coupling.
  • The architecture is language-agnostic and may support additional languages (e.g., Julia) in the future.

If rpy2 becomes reliably usable in all target environments, Polyester may optionally integrate with it.


Design Goals

  • ✅ Windows support
  • ✅ Minimal external dependencies
  • ✅ Simple, explicit API
  • ✅ Subprocess isolation
  • 🔄 Possible future multi-language support

Performance is important, but clarity and robustness are higher priorities at this stage.


Implementation Details

  • R is started as a background subprocess.
  • Communication happens over JSON Lines.
  • DataFrames are exchanged via Apache Arrow files.
  • Remote objects are reference-tracked and cleaned up automatically.

Status

Completed

  • Start R subprocess in background
  • JSON Lines protocol for communication
  • DataFrame transfer using Apache Arrow
  • Remote object lifecycle management

About

Call R functions from python code

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages