@compstats/core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/LICENSE +21 -0
- package/README.md +310 -0
- package/dist/3d.d.ts +33 -0
- package/dist/3d.d.ts.map +1 -0
- package/dist/3d.js +1984 -0
- package/dist/3d.js.map +22 -0
- package/dist/core/arith.d.ts +133 -0
- package/dist/core/arith.d.ts.map +1 -0
- package/dist/core/frame.d.ts +98 -0
- package/dist/core/frame.d.ts.map +1 -0
- package/dist/core/histogram.d.ts +68 -0
- package/dist/core/histogram.d.ts.map +1 -0
- package/dist/core/kde.d.ts +106 -0
- package/dist/core/kde.d.ts.map +1 -0
- package/dist/core/logit.d.ts +109 -0
- package/dist/core/logit.d.ts.map +1 -0
- package/dist/core/matrix.d.ts +135 -0
- package/dist/core/matrix.d.ts.map +1 -0
- package/dist/core/moderation.d.ts +127 -0
- package/dist/core/moderation.d.ts.map +1 -0
- package/dist/core/ols.d.ts +76 -0
- package/dist/core/ols.d.ts.map +1 -0
- package/dist/core/pca.d.ts +99 -0
- package/dist/core/pca.d.ts.map +1 -0
- package/dist/core/precision.d.ts +10 -0
- package/dist/core/precision.d.ts.map +1 -0
- package/dist/core/pretty.d.ts +51 -0
- package/dist/core/pretty.d.ts.map +1 -0
- package/dist/core/regression.d.ts +68 -0
- package/dist/core/regression.d.ts.map +1 -0
- package/dist/core/rng.d.ts +206 -0
- package/dist/core/rng.d.ts.map +1 -0
- package/dist/core/sampling.d.ts +157 -0
- package/dist/core/sampling.d.ts.map +1 -0
- package/dist/core/special.d.ts +92 -0
- package/dist/core/special.d.ts.map +1 -0
- package/dist/core/tdist.d.ts +53 -0
- package/dist/core/tdist.d.ts.map +1 -0
- package/dist/core/ttest.d.ts +146 -0
- package/dist/core/ttest.d.ts.map +1 -0
- package/dist/data/moderationData.d.ts +40 -0
- package/dist/data/moderationData.d.ts.map +1 -0
- package/dist/data/pcaDegenerate.d.ts +18 -0
- package/dist/data/pcaDegenerate.d.ts.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4195 -0
- package/dist/index.js.map +47 -0
- package/dist/interactive/controls.d.ts +97 -0
- package/dist/interactive/controls.d.ts.map +1 -0
- package/dist/interactive/logit.d.ts +57 -0
- package/dist/interactive/logit.d.ts.map +1 -0
- package/dist/interactive/matrixInverse.d.ts +86 -0
- package/dist/interactive/matrixInverse.d.ts.map +1 -0
- package/dist/interactive/moderation3d.d.ts +103 -0
- package/dist/interactive/moderation3d.d.ts.map +1 -0
- package/dist/interactive/pca.d.ts +90 -0
- package/dist/interactive/pca.d.ts.map +1 -0
- package/dist/interactive/regression.d.ts +57 -0
- package/dist/interactive/regression.d.ts.map +1 -0
- package/dist/interactive/sampling.d.ts +78 -0
- package/dist/interactive/sampling.d.ts.map +1 -0
- package/dist/interactive/scatter3d.d.ts +124 -0
- package/dist/interactive/scatter3d.d.ts.map +1 -0
- package/dist/interactive/tTest.d.ts +69 -0
- package/dist/interactive/tTest.d.ts.map +1 -0
- package/dist/interactive/target.d.ts +132 -0
- package/dist/interactive/target.d.ts.map +1 -0
- package/dist/plot/axes.d.ts +128 -0
- package/dist/plot/axes.d.ts.map +1 -0
- package/dist/plot/draw.d.ts +46 -0
- package/dist/plot/draw.d.ts.map +1 -0
- package/dist/plot/format.d.ts +33 -0
- package/dist/plot/format.d.ts.map +1 -0
- package/dist/plot/logit.d.ts +68 -0
- package/dist/plot/logit.d.ts.map +1 -0
- package/dist/plot/matrixInverse.d.ts +62 -0
- package/dist/plot/matrixInverse.d.ts.map +1 -0
- package/dist/plot/moderation3d.d.ts +135 -0
- package/dist/plot/moderation3d.d.ts.map +1 -0
- package/dist/plot/pca.d.ts +79 -0
- package/dist/plot/pca.d.ts.map +1 -0
- package/dist/plot/plotly.d.ts +209 -0
- package/dist/plot/plotly.d.ts.map +1 -0
- package/dist/plot/regression.d.ts +52 -0
- package/dist/plot/regression.d.ts.map +1 -0
- package/dist/plot/sampleCi.d.ts +82 -0
- package/dist/plot/sampleCi.d.ts.map +1 -0
- package/dist/plot/sampling.d.ts +159 -0
- package/dist/plot/sampling.d.ts.map +1 -0
- package/dist/plot/scatter3d.d.ts +164 -0
- package/dist/plot/scatter3d.d.ts.map +1 -0
- package/dist/plot/tTest.d.ts +49 -0
- package/dist/plot/tTest.d.ts.map +1 -0
- package/dist/plot/target.d.ts +55 -0
- package/dist/plot/target.d.ts.map +1 -0
- package/package.json +71 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@compstats/core`. The R package this ports keeps its
|
|
4
|
+
own history in [`NEWS.md`](https://github.com/compstatslib/compstatslib/blob/main/NEWS.md).
|
|
5
|
+
|
|
6
|
+
## 0.2.0
|
|
7
|
+
|
|
8
|
+
The first npm release. It follows the R package's own 0.8.0 release, which
|
|
9
|
+
settled the R public API before that package had users to break. The same
|
|
10
|
+
changes land here, for the same reason: nothing is published yet, so these are
|
|
11
|
+
renames rather than breaking changes with a deprecation cycle.
|
|
12
|
+
|
|
13
|
+
The number is 0.2.0, not 0.1.0, because 0.1.0 is a git tag that was never
|
|
14
|
+
published. It stays where it is, and the rename below is what moves the minor.
|
|
15
|
+
|
|
16
|
+
### Breaking changes
|
|
17
|
+
|
|
18
|
+
* `plotRegr()` is renamed `plotRegression()`, matching R's rename of
|
|
19
|
+
`plot_regr()` to `plot_regression()`. Every other plot function already
|
|
20
|
+
carried the name of its interactive counterpart; this was the last one that
|
|
21
|
+
did not. `PlotRegrOptions` and `regrScale()` are renamed with it, to
|
|
22
|
+
`PlotRegressionOptions` and `regressionScale()`. There is no shim.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
* `rt()`, `rlnorm()` and `rcauchy()` draw from the Student t, lognormal and
|
|
27
|
+
Cauchy distributions, with R's parameter names — `df`, `meanlog`/`sdlog`,
|
|
28
|
+
`location`/`scale`. One departure: `rt()` takes a positive integer `df`
|
|
29
|
+
only, where R's gamma sampler accepts any positive real. Empirical
|
|
30
|
+
quantiles are checked against R's `qt` and `qlnorm` over 200000 draws.
|
|
31
|
+
* `mean()`, `median()` and `meanAbsoluteDeviation()`. `median()` is R's own
|
|
32
|
+
rule, the type-7 quantile at 0.5. `meanAbsoluteDeviation()` is *not* R's
|
|
33
|
+
`mad()`, which is the median absolute deviation from the median and scaled
|
|
34
|
+
by 1.4826; the name is written in full because the abbreviation covers both
|
|
35
|
+
statistics. The sampling demonstration offers the last two as choices of
|
|
36
|
+
statistic.
|
|
37
|
+
* `kernelDensity()` takes `from` and `to`, R's own arguments, to fix the
|
|
38
|
+
reported window instead of taking it from the data.
|
|
39
|
+
* `plotSampling()` takes `densityWindow`. The default, `"data"`, is
|
|
40
|
+
unchanged. `"frozen"` puts the grid of every curve on the drawn window,
|
|
41
|
+
which a population reaching far outside that window needs: at 512 grid
|
|
42
|
+
points over a range a thousand times the window, one step is wider than the
|
|
43
|
+
panel and the curve draws as a straight line.
|
|
44
|
+
* `plotRegression()` takes `xlim` and `ylim`, R's own arguments. Both still
|
|
45
|
+
default to R's `c(-5, 50)`, and the mean crosshair clamps into a window
|
|
46
|
+
that does not contain 0.
|
|
47
|
+
* The two options above reach `interactiveRegression()` and
|
|
48
|
+
`interactiveSampling()` with no work, because each interactive options type
|
|
49
|
+
extends the plot options type it forwards.
|
|
50
|
+
|
|
51
|
+
### Bug fixes
|
|
52
|
+
|
|
53
|
+
* The sampling histogram is bounded by the window it draws in. A statistic
|
|
54
|
+
outside the shared window is clipped from the picture, so it must not set
|
|
55
|
+
the width of the histogram's cells either: one sample mean out at 800 made
|
|
56
|
+
every cell 100 units wide and left a single flat bar in a 124-wide panel.
|
|
57
|
+
The count in the panel label still reports the whole pile.
|
|
58
|
+
|
|
59
|
+
* `moderationSurface()` drops rows with missing values before fitting, as
|
|
60
|
+
R's `lm()` does with `na.action = na.omit`; it fit straight through NaN,
|
|
61
|
+
so one missing cell made every coefficient and all 225 surface heights
|
|
62
|
+
NaN. Fitted values and residuals keep input order with NaN marking the
|
|
63
|
+
dropped rows, a control is held at its finite mean (R's `hold_value()`
|
|
64
|
+
with `na.rm = TRUE`), and a model with no complete rows throws a
|
|
65
|
+
`RangeError`. One stated departure: R computes zlim with no `na.rm` and
|
|
66
|
+
fails on a missing outcome; the port draws what it fits.
|
|
67
|
+
* `moderation3dSpec()` refuses a surface with a non-finite height. A NaN
|
|
68
|
+
height field crashes WebGL inside plotly.js, and the crash poisons every
|
|
69
|
+
later 3D surface on the page; the spec now throws a `RangeError` before
|
|
70
|
+
the engine can see it.
|
|
71
|
+
* `plotMatrixInverse()` titles its axes `x` and `y`. R's `plot(NA, ...)`
|
|
72
|
+
deparsed its first argument into the titles, so the axes read "Index" and
|
|
73
|
+
"NA"; the port reproduced that by drawing no titles at all. R fixed it in
|
|
74
|
+
0.8.0 and this follows.
|
|
75
|
+
* `linearRegression()`, `logisticRegression()`, and `principalComponents()`
|
|
76
|
+
drop points with a non-finite coordinate before fitting, as R's `na.omit`
|
|
77
|
+
does and as `moderationSurface()` already did. The first fit straight
|
|
78
|
+
through NaN, the second refused it with a `RangeError`, and the third
|
|
79
|
+
answered all-NaN components. Fitted values, linear predictors, and scores
|
|
80
|
+
keep input order with NaN marking the dropped points; an input with no
|
|
81
|
+
complete point returns null, the existing "nothing to fit" answer.
|
|
82
|
+
`logisticRegression()` no longer throws on a non-finite predictor, and its
|
|
83
|
+
0-or-1 outcome rule now applies to the complete points alone. `logitScale()`
|
|
84
|
+
ignores a non-finite predictor too, so one missing value no longer poisons
|
|
85
|
+
the whole window.
|
|
86
|
+
* `scatter3dSpec()` and `moderation3dSpec()` emit scene axis titles in
|
|
87
|
+
Plotly's object form, `title: { text }`. Plotly v2 silently drops a
|
|
88
|
+
bare-string title, so no 3D plot ever showed its column names.
|
|
89
|
+
`PlotlyAxis.title` is typed to the object form for the same reason.
|
|
90
|
+
|
|
91
|
+
### Other
|
|
92
|
+
|
|
93
|
+
* Spelling is en-US throughout, as the R package now declares. No exported
|
|
94
|
+
name and no string a user reads changed — every correction was prose or an
|
|
95
|
+
internal identifier.
|
|
96
|
+
* The package ships a LICENSE, a README and this changelog.
|
|
97
|
+
* `prepublishOnly` runs the test suite, the type check and the build, so a
|
|
98
|
+
publish from a fresh clone cannot ship a stale or missing `dist/`.
|
|
99
|
+
* GitHub Actions runs the tests, the type check and the build on every push
|
|
100
|
+
and pull request.
|
|
101
|
+
|
|
102
|
+
## 0.1.0
|
|
103
|
+
|
|
104
|
+
Tagged in git, never published to npm.
|
|
105
|
+
|
|
106
|
+
The complete TypeScript port of the R package: all nine function families
|
|
107
|
+
across the three layers (`core/` statistics with no DOM, `plot/` renderers,
|
|
108
|
+
`interactive/` components), both bundled datasets exported from R, and a demo
|
|
109
|
+
page per family. The core statistics are asserted against conformance fixtures
|
|
110
|
+
computed in R.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-2026 Soumya Ray
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# @compstats/core
|
|
2
|
+
|
|
3
|
+
[](https://github.com/compstatslib/compstatslib-ts/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
Interactive gadgets and plotting functions for data sets and statistical
|
|
6
|
+
concepts, in two and three dimensions. This is the browser port of the R
|
|
7
|
+
package [`compstatslib`](https://github.com/compstatslib/compstatslib).
|
|
8
|
+
|
|
9
|
+
Some of it works on **your own data**. Explore any data frame as a rotatable
|
|
10
|
+
3D point cloud. Fit a moderated (interaction) regression and rotate its
|
|
11
|
+
surface to see how the interaction twists it away from a plane. The rest
|
|
12
|
+
**simulates a concept** instead of plotting your data — sampling
|
|
13
|
+
distributions, confidence intervals, t-statistics, matrix inversion. That part
|
|
14
|
+
is built for class demonstrations, homework, and self-study.
|
|
15
|
+
|
|
16
|
+
The R original runs in RStudio. This port runs in a browser, with no R
|
|
17
|
+
installation and no server. The 2D plots draw on a plain Canvas 2D context.
|
|
18
|
+
The 3D plots draw through Plotly, behind a separate entry point, so a page
|
|
19
|
+
that shows only 2D never loads it.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @compstats/core
|
|
25
|
+
# or
|
|
26
|
+
bun add @compstats/core
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Plotly is only needed for the 3D functions. See
|
|
30
|
+
[3D and Plotly](#3d-and-plotly) below.
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
Give an interactive component a canvas. It draws at once, and it redraws on
|
|
35
|
+
every click.
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<canvas id="plot" width="640" height="480"></canvas>
|
|
39
|
+
|
|
40
|
+
<script type="module">
|
|
41
|
+
import { interactiveRegression } from "@compstats/core";
|
|
42
|
+
|
|
43
|
+
const handle = interactiveRegression(document.querySelector("#plot"), {
|
|
44
|
+
onDone: (points) => console.log(points),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Later: read the state, clear it, or stop listening.
|
|
48
|
+
handle.getPoints();
|
|
49
|
+
handle.reset();
|
|
50
|
+
handle.destroy();
|
|
51
|
+
</script>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The plot functions draw the same picture from data you already hold, and
|
|
55
|
+
return what they computed:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
import { plotRegression } from "@compstats/core";
|
|
59
|
+
|
|
60
|
+
const fit = plotRegression(canvas, [
|
|
61
|
+
{ x: 1, y: 2 },
|
|
62
|
+
{ x: 2, y: 4 },
|
|
63
|
+
{ x: 3, y: 5 },
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
console.log(fit.slope, fit.rSquared);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The statistics are separate from the drawing. Import them alone when you want
|
|
70
|
+
the numbers and not the picture:
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
import { linearRegression, principalComponents, tTestStats } from "@compstats/core";
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Nothing in the `core/` layer touches the DOM, so it also runs under Node or
|
|
77
|
+
Bun.
|
|
78
|
+
|
|
79
|
+
## Use from a CDN
|
|
80
|
+
|
|
81
|
+
The main bundle is self-contained browser ESM with no imports of its own. A
|
|
82
|
+
page can load it directly, with no build step:
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<script type="module">
|
|
86
|
+
import { interactiveTTest } from "https://esm.sh/@compstats/core";
|
|
87
|
+
|
|
88
|
+
interactiveTTest(document.querySelector("#demo"));
|
|
89
|
+
</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
jsDelivr and unpkg serve the same file:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
import { interactiveTTest } from "https://cdn.jsdelivr.net/npm/@compstats/core/dist/index.js";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 3D and Plotly
|
|
99
|
+
|
|
100
|
+
The 3D functions live behind the `@compstats/core/3d` entry point:
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
import { interactiveScatter3d, moderationData } from "@compstats/core/3d";
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
That entry does not load Plotly either. It reaches the library through a
|
|
107
|
+
dynamic import the first time it draws. A caller that passes its own engine in
|
|
108
|
+
the `plotly` option never triggers that import:
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<script src="https://cdn.jsdelivr.net/npm/plotly.js-dist-min"></script>
|
|
112
|
+
|
|
113
|
+
<script type="module">
|
|
114
|
+
import { interactiveScatter3d, moderationData } from "https://esm.sh/@compstats/core/3d";
|
|
115
|
+
|
|
116
|
+
const handle = interactiveScatter3d(
|
|
117
|
+
document.querySelector("#demo"),
|
|
118
|
+
moderationData,
|
|
119
|
+
{ plotly: window.Plotly },
|
|
120
|
+
);
|
|
121
|
+
await handle.rendered();
|
|
122
|
+
</script>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Pass `plotly` when you load the 3D entry from a raw file CDN such as jsDelivr,
|
|
126
|
+
because nothing there resolves the bare `plotly.js-dist-min` specifier. esm.sh
|
|
127
|
+
rewrites bare specifiers, so on esm.sh both ways work.
|
|
128
|
+
|
|
129
|
+
## How the functions are organized
|
|
130
|
+
|
|
131
|
+
Every family has three parts, and you can use any one of them alone:
|
|
132
|
+
|
|
133
|
+
- a **core** function that computes the statistics and touches no DOM,
|
|
134
|
+
- a **plot** function that draws it on a target you give it,
|
|
135
|
+
- an **interactive** component that owns the input and hands each draw to the
|
|
136
|
+
plot function.
|
|
137
|
+
|
|
138
|
+
The families are grouped below by what they are *for*, because that varies
|
|
139
|
+
more than the interaction style does.
|
|
140
|
+
|
|
141
|
+
### Data sets in 3D
|
|
142
|
+
|
|
143
|
+
These accept any data frame, with control over axes, color mapping, aspect
|
|
144
|
+
ratio, and camera. They come from `@compstats/core/3d`.
|
|
145
|
+
|
|
146
|
+
| Function | What it does |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| `interactiveScatter3d(target, data, opts?)` | Rotatable 3D point cloud, with pickers for x / y / z and color, and sliders for aspect, opacity, and marker size. |
|
|
149
|
+
| `plotScatter3d(target, data, opts?)` | The same point cloud from a fixed set of options. |
|
|
150
|
+
| `interactiveModeration3d(target, data, opts)` | Fitted moderation surface as a 3D wireframe, with two rotation sliders. |
|
|
151
|
+
| `plotModeration3d(target, data, opts)` | The same surface at a stated viewing angle. |
|
|
152
|
+
| `moderationSurface(data, opts)` | The fit and the prediction grid behind both, as plain numbers. |
|
|
153
|
+
|
|
154
|
+
### 2D relationships
|
|
155
|
+
|
|
156
|
+
These plot x / y points you supply, together with a fitted model. They are
|
|
157
|
+
sized for small data — points clicked in by hand, or a modest table — and not
|
|
158
|
+
for arbitrary data. `plotRegression` draws in a window of -5 to 50 unless you
|
|
159
|
+
give it `xlim` and `ylim`, and the PCA functions expect points with an `x` and
|
|
160
|
+
a `y`.
|
|
161
|
+
|
|
162
|
+
| Function | What it does |
|
|
163
|
+
| --- | --- |
|
|
164
|
+
| `interactiveRegression(canvas, opts?)` | Click to add points. The line, the mean crosshair, and the statistics update on every click. |
|
|
165
|
+
| `plotRegression(target, points, opts?)` | The same picture from points you hold. Returns the fit. |
|
|
166
|
+
| `interactiveLogit(canvas, opts?)` | Click to add points. A logistic curve and its statistics update with them. |
|
|
167
|
+
| `plotLogit(target, points, opts?)` | The same picture from points you hold. |
|
|
168
|
+
| `interactivePca(canvas, opts?)` | Click to add points. The two component arrows appear from the third point and turn with every point after it. |
|
|
169
|
+
| `plotPca(target, points, opts?)` | The same picture, with optional mean centering. |
|
|
170
|
+
| `linearRegression(points)`, `logisticRegression(points, opts?)`, `principalComponents(points)` | The three fits, without a picture. |
|
|
171
|
+
|
|
172
|
+
### Simulations and concept demonstrations
|
|
173
|
+
|
|
174
|
+
These do not plot your data. They simulate a process, or draw a geometric
|
|
175
|
+
object, so that a concept can be watched instead of described.
|
|
176
|
+
|
|
177
|
+
| Function | What it does |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| `interactiveTTest(container, opts?)` | Sliders for difference, standard deviation, sample size, and alpha. The null and alternative t distributions, the rejection region, and the power redraw as they move. |
|
|
180
|
+
| `plotTTest(target, opts?)` | The same picture from fixed parameters. Returns the statistics. |
|
|
181
|
+
| `interactiveSampling(container, population, opts?)` | Draw samples from a population and watch the sampling statistic build up across repetitions. |
|
|
182
|
+
| `plotSampling(target, population, opts?)` | One draw of the three-panel picture. |
|
|
183
|
+
| `plotSampleCi(target, opts?)` | Repeated samples from a distribution function, each with its confidence interval, so that coverage becomes visible. |
|
|
184
|
+
| `interactiveMatrixInverse(container, opts?)` | Four sliders for the entries of a 2x2 matrix. The matrix and its inverse are drawn as parallelograms. |
|
|
185
|
+
| `plotMatrixInverse(target, matrix)` | The same picture from one matrix. Returns the determinant and the inverse. |
|
|
186
|
+
| `machinePrecision()` | The smallest number the runtime can add to 1. |
|
|
187
|
+
|
|
188
|
+
### Statistics without a picture
|
|
189
|
+
|
|
190
|
+
The R package never had to ship these. `mean()`, `sd()`, `quantile()`, `dt()`,
|
|
191
|
+
`rnorm()`, `density()`, `hist()`, `pretty()`, `solve()` and `lm.fit()` are all
|
|
192
|
+
in base R, and its functions call them. JavaScript has no statistics standard
|
|
193
|
+
library, so the port wrote them — and exports them, because an application
|
|
194
|
+
built on this package needs them for the same reason the package did.
|
|
195
|
+
|
|
196
|
+
| Group | Functions |
|
|
197
|
+
| --- | --- |
|
|
198
|
+
| Descriptives | `mean`, `median`, `sd`, `quantile`, `quantiles`, `meanAbsoluteDeviation` |
|
|
199
|
+
| Student t distribution | `dt`, `pt`, `qt`, with the `normalCdf`, `incompleteBeta` and `inverseIncompleteBeta` they stand on |
|
|
200
|
+
| Seeded random draws | `seededRng`, `runif`, `rnorm`, `rt`, `rlnorm`, `rcauchy`, `sampleWithoutReplacement` |
|
|
201
|
+
| Binning and density | `histogram`, `nclassSturges`, `kernelDensity`, `bwNrd0` |
|
|
202
|
+
| Axis ticks | `rPretty`, `prettyTicks` |
|
|
203
|
+
| Linear algebra | `leastSquares`, `determinant`, `invertMatrix` |
|
|
204
|
+
|
|
205
|
+
Each one follows its R counterpart, down to the rule and the argument names:
|
|
206
|
+
`quantile` is type 7, `nclassSturges` is Sturges' rule, `bwNrd0` is R's
|
|
207
|
+
`nrd0` bandwidth, `rPretty` is `pretty()`, and the samplers take R's own
|
|
208
|
+
parameters. The test suite pins them to values computed in R.
|
|
209
|
+
|
|
210
|
+
The draws take a generator you pass in, so a demonstration repeats exactly:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
import { seededRng, rnorm, quantile } from "@compstats/core";
|
|
214
|
+
|
|
215
|
+
const rng = seededRng(42);
|
|
216
|
+
const draws = rnorm(rng, 1000, { mean: 100, sd: 15 });
|
|
217
|
+
quantile(draws, 0.975);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Bundled data
|
|
221
|
+
|
|
222
|
+
`moderationData` (200 rows of `y`, `x`, `z`, `w`) and `pcaDegenerate` (16 rows
|
|
223
|
+
of `x`, `y`) are the same tables as in the R package, exported from R rather
|
|
224
|
+
than regenerated. Both are defaults, so a call with no data still gives a
|
|
225
|
+
working demonstration.
|
|
226
|
+
|
|
227
|
+
### Targets
|
|
228
|
+
|
|
229
|
+
The click-to-add-points components take a `<canvas>`. The components that own
|
|
230
|
+
sliders or menus take a container element and build their controls inside it.
|
|
231
|
+
Each one also accepts an explicit `{ surface, element }` pair when you want to
|
|
232
|
+
place the drawing surface and the controls yourself.
|
|
233
|
+
|
|
234
|
+
## Reproducing an interactive session
|
|
235
|
+
|
|
236
|
+
R's gadgets block until you click Done, and then print the `plot_*()` call
|
|
237
|
+
that reproduces the screen. Nothing blocks in a browser. Each component
|
|
238
|
+
returns a handle at once, and the handle carries the same state:
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
const handle = interactiveTTest(container);
|
|
242
|
+
|
|
243
|
+
handle.getValues(); // the state that reproduces the picture
|
|
244
|
+
handle.getStats(); // what the last draw computed
|
|
245
|
+
handle.done(); // hand the state to the onDone callback
|
|
246
|
+
handle.destroy(); // stop listening and remove what was built
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`getValues()` returns the options that draw the same picture again. Pass them
|
|
250
|
+
straight back to the matching plot function, or to the component itself. State
|
|
251
|
+
you would not retype has its own accessor: `getFit()` for PCA, `getState()`
|
|
252
|
+
for the accumulated sampling draws, `getSpec()` for the traces and layout of a
|
|
253
|
+
3D draw.
|
|
254
|
+
|
|
255
|
+
## Differences from the R package
|
|
256
|
+
|
|
257
|
+
The two packages compute the same statistics and draw the same pictures. The
|
|
258
|
+
R idioms that a browser has no answer for are handled like this:
|
|
259
|
+
|
|
260
|
+
- **Names.** `snake_case` becomes `camelCase`. `plot_regr()` is
|
|
261
|
+
`plotRegression()`, as it is in R since 0.8.0.
|
|
262
|
+
- **Signatures.** R's positional arguments and `...` become a data argument
|
|
263
|
+
and one options object.
|
|
264
|
+
- **Formulas.** `y ~ x * z` has no TypeScript counterpart. Name the columns
|
|
265
|
+
instead: `{ outcome: "y", iv: "x", mod: "z" }`.
|
|
266
|
+
- **Data frames.** Point sets are arrays of records. Bundled tables are
|
|
267
|
+
objects of columns.
|
|
268
|
+
- **Random numbers.** Draws take an injectable seeded generator, so a demo
|
|
269
|
+
repeats exactly. The stream does not match R's Mersenne Twister, and it is
|
|
270
|
+
not meant to.
|
|
271
|
+
- **Devices.** Every plot function takes an explicit target. There is no
|
|
272
|
+
current device.
|
|
273
|
+
|
|
274
|
+
One thing the port adds. It exports the statistical primitives that base R
|
|
275
|
+
hands the R package for free — descriptives, the t distribution, seeded
|
|
276
|
+
samplers, binning, density, axis ticks and small linear algebra, listed under
|
|
277
|
+
[Statistics without a picture](#statistics-without-a-picture). This is an
|
|
278
|
+
addition, not a divergence: each one follows its R counterpart's rule and is
|
|
279
|
+
tested against R's output.
|
|
280
|
+
|
|
281
|
+
The core statistics are asserted against values computed in R. The fixtures
|
|
282
|
+
live in the R package under `conformance-fixtures/`.
|
|
283
|
+
|
|
284
|
+
## Development
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
bun install
|
|
288
|
+
bun test
|
|
289
|
+
bun run typecheck
|
|
290
|
+
bun run build
|
|
291
|
+
bun run dev # demo site on http://localhost:3000
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Bun is the toolchain: runtime, package manager, test runner, and bundler. The
|
|
295
|
+
demo site runs one page per function family and is the fastest way to see a
|
|
296
|
+
change.
|
|
297
|
+
|
|
298
|
+
## Contributors
|
|
299
|
+
|
|
300
|
+
`@compstats/core` and `compstatslib` are maintained by Soumya Ray.
|
|
301
|
+
|
|
302
|
+
Daniele Melotti is a co-author of the R package. Several of the plotting and
|
|
303
|
+
interactive functions grew out of work he did as a student under Soumya Ray's
|
|
304
|
+
supervision, and were then folded back into the package.
|
|
305
|
+
|
|
306
|
+
Issues and pull requests are welcome.
|
|
307
|
+
|
|
308
|
+
## License
|
|
309
|
+
|
|
310
|
+
MIT. See [LICENSE](LICENSE).
|
package/dist/3d.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 3D entry point: `@compstats/core/3d`.
|
|
3
|
+
*
|
|
4
|
+
* The two 3D families of the R package draw through Plotly.js, which is four
|
|
5
|
+
* megabytes of browser code. They therefore live behind this entry rather than
|
|
6
|
+
* the main one, so that a page that draws only 2D plots never loads them.
|
|
7
|
+
*
|
|
8
|
+
* Nothing here loads Plotly either. `loadPlotly()` reaches the library through
|
|
9
|
+
* a dynamic import, which runs the first time a plot is drawn; a caller who
|
|
10
|
+
* passes its own engine through the `plotly` option never triggers it at all.
|
|
11
|
+
*
|
|
12
|
+
* The core statistics and the bundled data of the 3D families are re-exported
|
|
13
|
+
* here, so that one import covers a 3D page.
|
|
14
|
+
*/
|
|
15
|
+
export { loadPlotly } from "./plot/plotly";
|
|
16
|
+
export type { EyeCamera, PlotlyAxis, PlotlyCamera, PlotlyConfig, PlotlyHTMLElement, PlotlyLayout, PlotlyLike, PlotlyRelayoutEvent, PlotlyRelayoutUpdate, PlotlyScene, PlotlyTrace, Scatter3dMarker, Scatter3dTrace, SurfaceTrace, Vector3, } from "./plot/plotly";
|
|
17
|
+
export { DEFAULT_SCATTER3D_STYLE, plotScatter3d, scatter3dSpec, validateScatter3dStyle, } from "./plot/scatter3d";
|
|
18
|
+
export type { PlotScatter3dOptions, Scatter3dHandle, Scatter3dSpec, Scatter3dSpecOptions, Scatter3dStyle, Scatter3dTitles, } from "./plot/scatter3d";
|
|
19
|
+
export { interactiveScatter3d } from "./interactive/scatter3d";
|
|
20
|
+
export type { InteractiveScatter3dHandle, InteractiveScatter3dOptions, Scatter3dValues, } from "./interactive/scatter3d";
|
|
21
|
+
export { interactiveModeration3d } from "./interactive/moderation3d";
|
|
22
|
+
export type { InteractiveModeration3dHandle, InteractiveModeration3dOptions, Moderation3dValues, } from "./interactive/moderation3d";
|
|
23
|
+
export { resolvePlot3dTarget } from "./interactive/target";
|
|
24
|
+
export type { Plot3dPanel, Plot3dTarget, ResolvedPlot3dPanel, } from "./interactive/target";
|
|
25
|
+
export { cameraFromRotations, moderation3dSpec, plotModeration3d, } from "./plot/moderation3d";
|
|
26
|
+
export type { Moderation3dHandle, Moderation3dSpec, Moderation3dViewOptions, PlotModeration3dOptions, } from "./plot/moderation3d";
|
|
27
|
+
export { moderationSurface } from "./core/moderation";
|
|
28
|
+
export type { ModerationOptions, ModerationSurface, ModerationTerm, } from "./core/moderation";
|
|
29
|
+
export { frameRows, isNumericColumn, numericColumns, requireNumericColumn, requireThreeNumericColumns, } from "./core/frame";
|
|
30
|
+
export type { Column, DataFrame } from "./core/frame";
|
|
31
|
+
export { moderationData } from "./data/moderationData";
|
|
32
|
+
export type { ModerationData } from "./data/moderationData";
|
|
33
|
+
//# sourceMappingURL=3d.d.ts.map
|
package/dist/3d.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"3d.d.ts","sourceRoot":"","sources":["../src/3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,OAAO,GACR,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,YAAY,EACV,6BAA6B,EAC7B,8BAA8B,EAC9B,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|