dose-analyzer-response
v1.0.2
Published
JavaScript/TypeScript implementation of dose-response curve analysis
Maintainers
Readme
Dose Response Analyzer
A comprehensive TypeScript/JavaScript implementation of dose-response curve analysis equivalent to R's drc package. This module provides functionality for fitting multiple dose-response models and selecting the best model based on statistical criteria.
Features
- Multiple Model Types: Supports 2, 3, and 4-parameter logistic models (LL.2, LL.3, LL.4) equivalent to R's drc package
- Extended Models: Includes Gompertz, Weibull, exponential decay, and linear models
- Flexible Column Mapping: Works with any DataFrame column names through customizable mapping
- Statistical Analysis: Provides AIC, BIC, RMSE, and R² metrics for model comparison
- IC50 Calculation: Automatic extraction of IC50 values from fitted models
- TypeScript Support: Full TypeScript support with comprehensive type definitions
- Browser Compatible: Includes browser-compatible version with minimal DataFrame implementation
Installation
npm install dose-analyzer-responseFor TypeScript development:
npm install -D typescript @types/node ts-nodeQuick Start
TypeScript Usage
import { DoseResponseAnalyzer } from 'dose-analyzer-response';
import * as DataFrame from 'data-forge';
// Create sample data
const data = new DataFrame.DataFrame([
{ Compound: 'Drug_A', Conc: 0.1, Rab10: 0.95 },
{ Compound: 'Drug_A', Conc: 1.0, Rab10: 0.85 },
{ Compound: 'Drug_A', Conc: 10.0, Rab10: 0.65 },
// ... more data points
]);
// Initialize analyzer
const analyzer = new DoseResponseAnalyzer({
enableCustomModels: true,
initialGuessStrategy: 'adaptive'
});
// Fit models
const results = analyzer.fitBestModels(data);
// Access results
console.log('Best Models:', results.bestModels.toArray());
console.log('IC50 Values:', results.bestModels.toArray().map(m => ({
compound: m.Compound,
ic50: m.IC50,
model: m.Model
})));
// Generate prediction curves
const compound = 'Drug_A';
if (results.bestFittedModels[compound]) {
const curve = analyzer.predictCurve(results.bestFittedModels[compound]);
console.log('Prediction curve generated with', curve.concentration.length, 'points');
}JavaScript Usage
const DoseResponseAnalyzer = require('dose-analyzer-response');
const DataFrame = require('data-forge');
// Same API as TypeScript but without type annotations
const analyzer = new DoseResponseAnalyzer({
enableCustomModels: true,
initialGuessStrategy: 'adaptive'
});
const results = analyzer.fitBestModels(data);Browser Usage
<!DOCTYPE html>
<html>
<head>
<script src="dose-response-analyzer.browser.js"></script>
</head>
<body>
<script>
// Create example data
const data = DoseResponseAnalyzer.createExampleData();
// Initialize analyzer
const analyzer = new DoseResponseAnalyzer({
enableCustomModels: true
});
// Fit models
const results = analyzer.fitBestModels(data);
console.log('Analysis complete!', results);
</script>
</body>
</html>Custom Column Mapping
The analyzer can work with any DataFrame column structure:
// Your data has different column names
const customData = new DataFrame.DataFrame([
{ Drug_ID: 'Compound_1', Dose_uM: 0.1, Viability: 0.95 },
// ... more data
]);
// Map your column names to the expected structure
const columnMapping = {
compound: 'Drug_ID',
concentration: 'Dose_uM',
response: 'Viability'
};
const analyzer = new DoseResponseAnalyzer({ columnMapping });
const results = analyzer.fitBestModels(customData);Configuration Options
interface AnalyzerOptions {
columnMapping?: {
compound: string;
concentration: string;
response: string;
};
maxIterations?: number; // Default: 10000
tolerance?: number; // Default: 1e-8
selectionMetric?: 'rmse' | 'aic' | 'bic' | 'r2'; // Default: 'rmse'
enableCustomModels?: boolean; // Default: true
initialGuessStrategy?: 'fixed' | 'data_driven' | 'adaptive'; // Default: 'adaptive'
outlierDetection?: boolean; // Default: false
confidenceInterval?: boolean; // Default: false
bootstrapSamples?: number; // Default: 1000
}Available Models
Basic Logistic Models
- model1 (LL.2): 2-parameter logistic
f(x) = top / (1 + x/ic50) - model2 (LL.3): 3-parameter logistic
f(x) = bottom + (top-bottom) / (1 + x/ic50) - model3 (LL.4): 4-parameter logistic
f(x) = bottom + (top-bottom) / (1 + (x/ic50)^hillslope) - model4: 3-parameter with bottom fixed at 0
- model5: 4-parameter with bottom fixed at 0
- model6: 4-parameter with bottom=0 and hillslope=1
Extended Models (when enableCustomModels: true)
- gompertz: Gompertz growth model
- weibull: Weibull dose-response model
- exponential: Exponential decay model
- linear: Linear dose-response model
API Reference
DoseResponseAnalyzer
Methods
fitBestModels(df): Fit all models and return best fit for each compoundfitSingleModel(concentration, response, modelName, modelSpec): Fit a specific modelpredictCurve(compoundResult, concentrationRange?, nPoints?): Generate smooth prediction curvegetColumns(): Get current column mappinggetModelSpecs(): Get available model specifications
Results Structure
interface AnalysisResults {
summaryTable: DataFrame<any>; // All model fits with metrics
bestModels: DataFrame<any>; // Best model for each compound
bestFittedModels: { // Fitted model objects
[compound: string]: CompoundResult
};
allResults: { // All fitted models
[key: string]: CompoundResult
};
}Examples
Run the included examples:
# TypeScript example
npm run example-ts
# JavaScript example
npm run example
# Browser example
npm run browser-exampleDevelopment
Building from Source
# Install dependencies
npm install
# Build TypeScript to JavaScript
npm run build
# Run tests
npm testLicense
MIT License - see LICENSE file for details.
