## 📋 Working with Tables

Tables allow you to manage multiple columns, filter data, create new computed columns, perform statistical comparisons — and now also run **linear regression** directly.

---

### 🛠️ Creating a Table and Adding Columns

You can initialize a table with or without data:

```js
const table = Statistics.newTable();
table.addColumn("Scores", [10, 20, 30, 40]);
table.addColumn("Grades", ["A", "B", "C", "D"]);
```

Or create with data immediately:

```js
const table = Statistics.newTable({
  Scores: [10, 20, 30, 40],
  Grades: ["A", "B", "C", "D"]
});
```

> Column types (`RatioColumn` or `Column`) are auto-detected.

---

### ➕ Adding Rows

```js
table.addRow({ Scores: 50, Grades: "F" }); // Adds to the end
table.addRow({ Scores: 5, Grades: "A+" }, 0); // Inserts at index 0
```

Returns `true` if successful, `false` if structure or types don’t match.

---

### 🔍 Row Filtering

```js
// Exclude specific rows by index
table.filterRows([1]);
console.log(table.columns["Scores"].values); // [10, 30, 40]

// Filter by values using column-level filter
table.clearAllRowsFilters();
table.filterRowsBy("Scores", v => v > 20);
console.log(table.columns["Scores"].values); // [10, 20]
console.log(table.columns["Grades"].values); // ["A", "B"]

// Reset filters
table.clearAllRowsFilters();
```

---

### 🧮 Computing New Columns

Use any logic to generate new columns:

```js
table.compute(({ Scores }) => Scores * 2, "Doubled");
console.log(table.columns["Doubled"].values); // [20, 40, 60, 80]
```

> Uses the row-wise structure: `({ Col1, Col2 }) => ...`

---

### 🔎 Filtering with `.where(...)`

Returns matching row indexes (ignoring filtered rows):

```js
const indexes = table.where(({ Scores }) => Scores > 15);
console.log(indexes); // [1, 2, 3] if "Scores" > 15
```

---

### 🔁 Transposing the Table

Turns rows into columns:

```js
const transposed = table.transpose();
console.log(transposed.columns["0"].values); // [10, "A"]
```

---

### 📈 Running Linear Regression

Perform regression right from the table:

```js
const model = table.linearRegression("Scores", ["Doubled"]).calculate();
console.table(model.result);
```

- `table.linearRegression(y, x)` is a shortcut for `new LinearRegression(...)`
- Supports `.mediator(...)`, `.moderator(...)`, and `.calculate()` chaining

---

### 📊 Aggregating Metrics (Descriptive)

```js
const means = table.descriptive("mean");
console.log(means.columns["Scores"].values[0]); // e.g. 25
```

Any column-level metric is supported, like `"stdDevSample"`, `"cv"`, `"flatness"`, etc.

---

### 🧪 Comparing Two Columns

```js
const comp = table.compare("Scores", "Doubled");
console.log(comp.correlationSample); // e.g. 1.0
```

Returns a `Comparative` object, which supports:
- `correlationSample`, `correlationPopulation`
- `covarianceSample`, `covariancePopulation`
- `pearsonSample`, `pearsonPopulation`
- `twoSampleTTest()`

---

### 📦 Cloning Tables

You can duplicate the table with filters and/or selected columns:

```js
// Clone with all columns and current row filters
const fullClone = table.clone(true);
console.log(fullClone.columns["Scores"].values); // [10, 20, 30, 40]

// Clone with selected columns
const selectedClone = table.clone(true, ["Scores"]); // Only "Scores"
console.log(selectedClone.columns["Scores"].values); // [10, 20, 30, 40]
console.log(selectedClone.columns["Grades"]); // undefined

// Clone excluding columns
const excludedClone = table.clone(true, ["-Grades"]); // All except "Grades"
console.log(excludedClone.columns["Scores"].values); // [10, 20, 30, 40]
console.log(excludedClone.columns["Grades"]); // undefined

// Clone with regex filter
table.addColumn("Scores2", [1, 2, 3, 4]);
const regexClone = table.clone(true, [/^Scores/]); // Columns starting with "Scores"
console.log(regexClone.columns["Scores"].values); // [10, 20, 30, 40]
console.log(regexClone.columns["Scores2"].values); // [1, 2, 3, 4]
```

- **Options for `clone(filtered, columnFilter)`:**
  - `filtered`: `true` (keep row filters) or `false` (use original data).
  - `columnFilter`: Array of filters:
    - `"Name"`: Include this column.
    - `"-Name"`: Exclude this column (if no includes specified).
    - `/pattern/`: Include columns matching the regex.
  - **Note:** If explicit includes (e.g., `"A"`) are used, exclusions (e.g., `"-B"`) are ignored.

---


### 🧹 Removing Columns

```js
table.deleteColumn("Grades");
console.log(table.columns["Grades"]); // undefined
```

---

### 🚀 Available Methods

| Method                         | Description                                                  |
|--------------------------------|--------------------------------------------------------------|
| `addColumn(name, values)`     | Adds new column with auto-detection.                        |
| `addRow(obj, index?)`         | Appends or inserts a row.                                   |
| `compute(fn, name?)`          | Computes a new column.                                      |
| `compare(col1, col2)`         | Returns statistical comparison object.                      |
| `filterRows(indexes)`         | Excludes rows by index.                                     |
| `filterRowsBy(name, fn)`      | Filters rows based on column values.                        |
| `clearAllRowsFilters()`       | Removes all filters.                                        |
| `clone(filtered, filterCols)` | Returns new table with selected rows/columns.               |
| `descriptive(metric)`         | Returns a new table with a summary metric per column.       |
| `transpose()`                 | Flips rows and columns.                                     |
| `where(fn)`                   | Returns indexes of matching rows.                           |
| `dbscan(eps, minPts)`         | Runs DBSCAN clustering on columns.                          |
| `hdbscan(minPts)`             | Runs HDBSCAN clustering (hierarchical).                     |
| `linearRegression(y, x?)`     | Returns a new `LinearRegression` instance for the table.    |

---

