# Quick start

## Start a bridge

Use `RBridge` as a context manager — R starts when you enter the block and is
cleanly shut down when you leave.

```python
from r_bridge import RBridge

with RBridge() as r:
    ...
```

You can also manage the lifecycle manually:

```python
r = RBridge()
r.start()
# ... do work ...
r.stop()
```

## Set and get variables

Assign Python values to attributes on `r` and they appear in R's global
environment. Reading an attribute fetches the value back from R.

```python
with RBridge() as r:
    r.x = 42
    r.label = "hello"
    r.values = [1.0, 2.5, 3.0]

    print(r.x)       # 42
    print(r.label)   # "hello"
    print(r.values)  # numpy array([1., 2.5, 3.])
```

## Call R functions

Accessing any name that is not a variable in R returns a callable proxy. Arguments
and keyword arguments are serialised and forwarded as positional and named R arguments.

```python
with RBridge() as r:
    r.v = [1, 2, 3, 4, 5]

    print(r.sum(r.v))          # 15
    print(r.mean(r.v))         # 3.0
    print(r.sd(r.v))           # 1.581...

    # Keyword arguments become named R arguments
    print(r.seq(1, 10, by=2))  # [1, 3, 5, 7, 9]
    print(r.paste("hello", "world", sep="-"))  # "hello-world"
```

## Evaluate R expressions

Use `r.eval()` to send arbitrary R code:

```python
with RBridge() as r:
    result = r.eval("2 ^ 10")                    # 1024.0
    r.eval("model <- lm(y ~ x, data = df)")      # no return value
    coefs = r.eval("coef(model)", result_type_hint="list")
```

## numpy and pandas

numpy arrays and pandas DataFrames are converted automatically:

```python
import numpy as np
import pandas as pd
from r_bridge import RBridge

with RBridge() as r:
    # numpy
    r.mat = np.array([[1, 2], [3, 4]], dtype=float)
    print(r.det(r.mat))   # -2.0

    # pandas
    r.df = pd.DataFrame({"x": [1, 2, 3], "y": [2.1, 4.0, 5.9]})
    r.eval("model <- lm(y ~ x, data = df)")
    print(r.eval('coef(model)[["x"]]', result_type_hint="scalar"))
```

## Execute multi-line scripts

Use `r.execute()` when you want to run a block of R code as a script and do
not need the return value — defining functions, loading data, running loops:

```python
with RBridge() as r:
    r.execute("""
        square <- function(x) x ^ 2
        results <- sapply(1:5, square)
    """)
    print(r.results)   # numpy array([1, 4, 9, 16, 25])
```

`execute` always returns `None`. If you need the result of the last
expression, use `eval` instead.

## Verbose mode

Pass `verbose=True` to trace all R calls and R output in real time:

```python
with RBridge(verbose=True) as r:
    r.x = [1, 2, 3]
    r.mean(r.x)
```

```
[R set]  x = ...
[R call] mean([...])
```

See [Verbose mode](error-handling.md) for details.
