# EventTime


A vector of event times that may be exact, or right-, left-, or interval-censored.


Usage

``` python
EventTime()
```


Create one with `event_time()`, which validates its input, or with [new_event_time()](new_event_time.md#greenwood.new_event_time), which only checks types.

Each element has a time and a single-letter status: `"e"` (exact event), `"r"` (right-censored), `"l"` (left-censored), or `"i"` (interval-censored, with an upper bound in `time_max`). Elements print as `7` for an event, `5+` for right censoring, `3-` for left censoring, and `[2, 4]` for an interval.

The vector supports `len()`, indexing with an integer, a slice, an integer array, or a boolean mask (always returning an [EventTime](EventTime.md#greenwood.EventTime)), and [EventTime.concat()](EventTime.md#greenwood.EventTime.concat) to combine vectors. Use [extract_time()](extract_time.md#greenwood.extract_time) and [extract_status()](extract_status.md#greenwood.extract_status) to get the components back, and [to_frame()](EventTime.md#greenwood.EventTime.to_frame) for a table with `time`, `status`, and `time_max` columns.


## Examples


``` python
import greenwood as gw

x = gw.event_time(
    time=[7, 5, 3, 2, None],
    status=["e", "r", "l", "i", None],
    time_max=[None, None, None, 4, None],
)
x
```


    <event_time[5]>
    7      5+     3-     [2, 4] <NA>


Indexing returns another [EventTime](EventTime.md#greenwood.EventTime):


``` python
x[1:4]
```


    <event_time[3]>
    5+     3-     [2, 4]


## Methods

| Name | Description |
|----|----|
| [__getitem__()](#__getitem__) | Select elements, returning a new event-time vector. |
| [concat()](#concat) | Combine event-time vectors end to end, as `c()` does in R. |
| [format()](#format) | Format each element as text, with `None` for missing elements. |
| [is_na()](#is_na) | Return which elements are missing. |
| [to_frame()](#to_frame) | Split the vector into a table with `"time"`, `"status"`, and `"time_max"` columns. |

------------------------------------------------------------------------


### \_\_getitem\_\_()


Select elements, returning a new event-time vector.


Usage

``` python
__getitem__(key)
```


Indexing always returns an [EventTime](EventTime.md#greenwood.EventTime), even for a single element. Each element keeps its time, status, and upper bound. Negative integers count from the end, as usual in Python (R's `x[-1]`, which drops an element, has no equivalent here).


#### Parameters


`key: Any`  
An integer, a slice, an array of integer positions, or a boolean mask with one value per element.


#### Returns


`EventTime`  
The selected elements.


#### Raises


`IndexError`  
If an integer position is out of range.

`TypeError`  
If `key` is not an integer, a slice, an integer array, or a boolean mask.


#### Examples


``` python
import greenwood as gw

x = gw.event_time(
    time=[7, 5, 3, 2, None],
    status=["e", "r", "l", "i", None],
    time_max=[None, None, None, 4, None],
)
x[1:4]
```


    <event_time[3]>
    5+     3-     [2, 4]


A boolean mask keeps the elements where it is `True`, here the complete ones:


``` python
x[~x.is_na()]
```


    <event_time[4]>
    7      5+     3-     [2, 4]


------------------------------------------------------------------------


### concat()


Combine event-time vectors end to end, as `c()` does in R.


Usage

``` python
concat(items)
```


The elements of each vector are placed one after another, in the order given. Each keeps its time, status, and upper bound, so vectors with different kinds of censoring can be combined freely. Combining an empty list gives an empty vector.


#### Parameters


`items: Iterable[EventTime]`  
The [EventTime](EventTime.md#greenwood.EventTime) vectors to combine, in order.


#### Returns


`EventTime`  
A vector holding every element of `items`.


#### Raises


`TypeError`  
If any item is not an [EventTime](EventTime.md#greenwood.EventTime). As in R, an event-time vector can't be combined with plain numbers. Build them into an [EventTime](EventTime.md#greenwood.EventTime) first with `event_time()`.


#### Examples


``` python
import greenwood as gw

a = gw.event_time(time=[7, 5], status=["e", "r"])
b = gw.event_time(time=[1], status=["i"], time_max=[3])
gw.EventTime.concat([a, b])
```


    <event_time[3]>
    7      5+     [1, 3]


------------------------------------------------------------------------


### format()


Format each element as text, with `None` for missing elements.


Usage

``` python
format()
```


This is the text the vector's printout shows, one string per element. Every number in the vector is formatted together with R's rules: at most 7 significant digits, a shared number of decimal places, and scientific notation when that is narrower. Then each element is marked by its status:

- Exact events get a trailing space: `"7 "`.
- Right-censored values get a `+`: `"5+"`.
- Left-censored values get a `-`: `"3-"`.
- Interval-censored values are written as `"[lower, upper]"`.


#### Returns


`list of str or None`  
One string per element, or `None` where the element is missing.


#### Examples


``` python
import greenwood as gw

x = gw.event_time(time=[7, 5.5, 3], status=["e", "r", "i"], time_max=[None, None, 4])
x.format()
```


    ['7.0 ', '5.5+', '[3.0, 4.0]']


Very different magnitudes share one layout, switching to scientific notation as R does:


``` python
gw.event_time(time=[0.001234, 12345.6, 7], status=["e", "r", "l"]).format()
```


    ['1.23400e-03 ', '1.23456e+04+', '7.00000e+00-']


------------------------------------------------------------------------


### is_na()


Return which elements are missing.


Usage

``` python
is_na()
```


An element is missing when any of its times is missing (`nan`). For an interval-censored element that includes a missing upper bound. A missing status alone only occurs together with a missing time, because `event_time()` rejects a missing status where the time is present. Estimators drop missing elements when fitting.


#### Returns


`numpy.ndarray`  
A boolean array with one value per element, `True` where the element is missing.


#### Examples


``` python
import greenwood as gw

x = gw.event_time(time=[7, None, 2], status=["e", None, "i"], time_max=[None, None, 4])
x.is_na()
```


    array([False,  True, False])


Select the complete elements with the inverted mask:


``` python
x[~x.is_na()]
```


    <event_time[2]>
    7      [2, 4]


------------------------------------------------------------------------


### to_frame()


Split the vector into a table with `"time"`, `"status"`, and `"time_max"` columns.


Usage

``` python
to_frame(
    *,
    format=None,
)
```


This is the reverse of `event_time()`, with one row per element. The `"time_max"` column is always included, and is missing for elements that are not interval-censored. Missing values are nulls. Use the table to inspect a vector, to join it back onto other data, or to export it.


#### Parameters


`format: str | None = None`  
Output format: `None` (default), `"pandas"`, `"polars"`, or `"pyarrow"`. When `None`, a backend is auto-detected (Polars, then Pandas, then PyArrow).


#### Returns


`pandas.DataFrame, polars.DataFrame, or pyarrow.Table`  
One row per element, with the columns `"time"`, `"status"`, and `"time_max"`.


#### Raises


`ImportError`  
If the requested DataFrame library (or, with `format=None`, any of them) is not installed.


#### Examples


``` python
import greenwood as gw

x = gw.event_time(time=[7, 5, 2], status=["e", "r", "i"], time_max=[None, None, 4])
x.to_frame(format="polars")
```


shape: (3, 3)

| time | status | time_max |
|------|--------|----------|
| f64  | str    | f64      |
| 7.0  | "e"    | null     |
| 5.0  | "r"    | null     |
| 2.0  | "i"    | 4.0      |
