Writing your own wrapper

The built-in wrappers are thin subclasses of rbartpackages.base.RObjectBase; you can wrap any R function the same way.

First install the R package to wrap, e.g. BART from CRAN:

install.packages("BART")

Then subclass RObjectBase, setting _rfuncname to the R function to call. R methods of the result are bound with rmethod; the decorated body is discarded, so a stub suffices:

from functools import partial
from rbartpackages.base import RObjectBase, rmethod

class gbart(RObjectBase):
    _rfuncname = 'BART::gbart'

    @partial(rmethod, rname='predict')
    def predict(self, newdata, *args, **kw): ...

That’s all. Calling the class runs BART::gbart with the arguments converted to R, and the components of the returned R object become Python attributes:

import numpy as np

x = np.random.randn(100, 3)
y = x[:, 0] + 0.1 * np.random.randn(100)

fit = gbart(x_train=x, y_train=y, ndpost=200)
fit.yhat_train.shape  # (200, 100)
fit.predict(x).shape  # (200, 100)

The upstream R documentation is appended to the class docstring, so help(gbart) shows the reference of BART::gbart.

The conversion is mechanical, so R idiosyncrasies show through. For example, R has no scalars, only length-1 vectors, which convert to length-1 arrays:

fit.offset  # array([-0.1063...]) — not a float

The built-in wrappers smooth out these rough edges: rbartpackages.BART.gbart unwraps the scalars, converts R’s 1-based indices, and documents every attribute. Prefer them when one exists.