A Node JS package for data wrangling and analysis
Both Javascript and Node already have a variety of packages that deal with dataframes and statistical computation. The goal with Nodestat is to demonstrate a unified grammar of data analysis that can transform Javascript into a fully capable language for data analysis. Specific design goals are as follows:
-
An Intuitive Grammar. Even without a third party package, Javascript already contains some functionality for handling data using Javascript Objects and JSON. In fact, many of the base functions that Nodestat implements through its
Dataframemodule are hardly novel and can be written by any experienced Javascript developer. With Nodestat, however, the aim is to create a grammar for data analysis that is intuitive and efficient, allowing the same split-apply-combine strategy for data wrangling that theplyr/dplyrpackage provides for the R language, and thatpandasprovides for the Python language. -
Close Integration with Statistical Packages. The
Dataframemodule isn't just another package for handling data in Javascript. It's designed to play well with packages for data analysis and statistical computation. TheStatsmodule demonstrates this capability. In the future, hopefully additional modules and independent packages will be developed following theDataframegrammar for more advanced data analysis and machine learning.
If you are interested in contributing to this project, please see our contribution guidelines for more information.
Install using NPM as
$ npm install @dominicdayta/nodestatThe package currently contains three primary modules:
stat: Contains basic statistical formulas, tests, datasets, and linear models (stat.lm / nstat.lm).
df: Contains useful functions for creating and managing dataframes.
random: Seedable random number generation and object-oriented probability distributions.
const nstat = require('@dominicdayta/nodestat');
let stats = nstat.stat; // for shorthand
// initiate the titanic dataset
let titanic = stats.dataset("Titanic");
// get the subset containing only survivors
let titanicSurvivors = titanic.subset(col = "Survived",
function(x){
return(x == "Yes")
}
);
console.log(titanicSurvivors.data);
// aggregate the total number of survivors by sex and class
let freqSurvivedBySexClass = titanic
.select(["Class","Sex","Freq"])
.aggregate(by = ["Class","Sex"], stats.sum);
console.log(freqSurvivedBySexClass.data);
// aggregate the total number of non-survivors by sex and age
let freqDiedSexAge = titanic
.subset(col = "Survived", function(x){return(x == "No")})
.select(["Sex","Age","Freq"])
.aggregate(by = ["Sex","Age"], stats.sum)
.data;
console.log(freqDiedSexAge);
// sort using helper syntax (similar to dplyr::arrange)
let sorted = titanic.order(["Class", nstat.desc("Freq")]);
console.log(sorted.head(5).data);Nodestat provides a seedable random API with distribution objects similar to NumPy and PyTorch. Create a distribution, then call pdf, cdf, and sample:
const nstat = require('@dominicdayta/nodestat');
// reproducible sampling
nstat.random.set_global_seed(2026);
const normal = nstat.random.normal(0, 1);
console.log(normal.pdf(0));
console.log(normal.cdf(1.96));
console.log(normal.sample(5));
const pois = nstat.random.poisson(3);
console.log(pois.pmf(2));
console.log(pois.sample());Supported distributions include normal, exponential, gamma, geometric, uniform, poisson, binomial, chi-square, Student's t, and hypergeometric. See random module docs for the full reference.
Nodestat includes R-style hypothesis testing under stat.tests:
const nstat = require('@dominicdayta/nodestat');
const sleep = nstat.stat.dataset('sleep');
// one-way ANOVA
const model = nstat.stat.tests.aov('extra ~ group', sleep);
console.log(model.statistic, model.p_value);
// Tukey HSD pairwise comparisons
console.log(nstat.stat.tests.tukeyHSD(model).comparisons);
// multiple-comparison p-value adjustment
console.log(nstat.stat.tests.p_adjust([0.01, 0.04, 0.03], 'holm'));Supported procedures include one- and two-sample t-tests, Wilcoxon tests, ANOVA with Tukey HSD, and Bonferroni/Holm/Hochberg/BY p-value adjustment. See statistical tests docs.
Fit object-oriented linear models with formula syntax similar to R's lm():
const nstat = require('@dominicdayta/nodestat');
const women = nstat.stat.dataset('women');
const model = nstat.lm('weight ~ height', women);
console.log(model.coef());
console.log(model.summary());
console.log(model.coeftable().print());Formulas support interactions (x * group), transforms (log(y) ~ sqrt(x)), and as-is terms (I(x^2)). Categorical predictors are automatically dummy-coded. See linear models docs.
You can look into sample runnable use cases in the ./examples directory (legacy examples are in ./demo). For full documentation on how to use the API, please look into the ./docs directory.
This package is licensed under the MIT License.