# How `fit!`

Works

## Core Principles

- Stats are subtypes of
`OnlineStat{T}`

where`T`

is the type of a single observation.- E.g.
`Mean <: OnlineStat{Number}`

- E.g.
`fit!(o::OnlineStat{T}, data::T)`

- Update
`o`

with the single observation`data`

.

- Update
`fit!(o::OnlineStat{T}, data::S)`

- Iterate through
`data`

and`fit!`

each item.

- Iterate through

## Why is Fitting Based on Iteration?

### Reason 1: OnlineStats doesn't make assumptions on the shape of your data

Consider `CovMatrix`

, for which a single observation is an `AbstractVector`

, `Tuple`

, or `NamedTuple`

. If I try to `fit!`

it with a `Matrix`

, it's ambiguous whether I want *rows* or *columns* of the matrix to be treated as individual observations.

See ** eachrow** and

**(after typing**

`eachcol`

`using LinearAlgebra`

).```
x = randn(1000, 2)
fit!(CovMatrix(), eachrow(x))
fit!(CovMatrix(), eachcol(x'))
```

`CovMatrix: n=1000 | value=[0.989115 -0.0513987; -0.0513987 1.08399]`

### Reason 2: OnlineStats works out-of-the-box with many data structures

Tabular data structures such as those in JuliaDB iterate over named tuples of rows, so things like this just work:

```
using JuliaDB
t = table(randn(100), randn(100))
fit!(2Mean(), t)
```

## A Common Error

Consider the following example:

`julia> fit!(Mean(), "asdf")`

`ERROR: The input for Mean is Number. Found Char.`

This causes an error because:

`"asdf"`

is not a`Number`

, so OnlineStats attempts to iterate through it- Iterating through
`"asdf"`

begins with the character`'a'`