Frequency
- API Reference Data.FrequencyMutable class
- Trackers track data ranges
The FrequencyMutable
class keeps track of the number of times a certain value is 'seen'.
In some scenarios it can be useful to aggregate data over time, rather than looking at a single event or snapshot-in-time. It allows you to do some fuzzy logic, for example using the value that mostly occurs.
In the demo below, a weighted distribution of random numbers is produced, with lower numbers occuring more often than higher numbers. A FrequencyMutable
instance is used to count how many times each number appears, and for visualisation purposes shown as a histogram.
Usage
frequencyMutable
creates a new instance. The provided frequency histogram is mutable, meaning that the object reference stays the same while the data inside is permitted to change.
Adding and clearing
// repl-pad#1
import { frequencyMutable } from "https://unpkg.com/ixfx/dist/data.js"
// Create an instance
const freq = frequencyMutable();
// Add data, here several at once
freq.add(`apples`, `oranges`, `apples`, `pears`, `pears`);
// Get an array version
// [ ["apples", 2], ["oranges",1],["pears",2] ]
const t = freq.toArray();
Clear all data
freq.clear();
Working with frequency
Get the count of a specific group. Returns undefined
if group is not found.
// repl-pad#1
const f = freq.frequencyOf(`apples`); // 2
It can be useful to work with the relative frequency rather than the absolute amount. For example, apples
appears 40% of the time:
// repl-pad#1
const rel = freq.relativeFrequencyOf(`apples`); // 0.4
To find the smallest, largest, average frequencies as well as the total frequency (ie. how many things have been added):
// repl-pad#1
// Returns {min, max, avg, total}
const mma = freq.minMaxAvg();
console.log(`Average frequency is ${mma.avg}`);
Iterating
You can get the data as an array and iterate:
// repl-pad#1
const data = freq.entries(); // freq.toArray() gives same result
for (const [group, count] of data) {
console.log(`${group} has a count of ${count}`); // apples has a count of 2...
}
To get the entries sorted:
// repl-pad#1
// Sorting options are: value, valueReverse, key or keyReverse
const sorted = freq.entriesSorted(`key`); // Sort alphabetically by key
Custom objects
To keep track of objects, provide a function that creates a string for the items you're adding. This allows you to group by different fields, or some combination of fields.
In the below example, cars are grouped by their make:
// repl-pad
import { frequencyMutable } from "https://unpkg.com/ixfx/dist/data.js"
// Two cars
const cars = [
{
make: `Toyota`,
model: `Corolla`,
year: 1980
},
{
make: `Honda`,
model: `Civic`,
year: 1985
}
]
// Count cars by make
const freq = frequencyMutable(car => car.make);
// Add array of cars
freq.add(...cars);
// Count a group
freq.frequencyOf(`Toyota`); // 1
// Or by object, which uses the same stringify function
freq.frequencyOf(cars[1]); // 1
Examples
Letter frequency
The below example calculates frequency distribution of letters in a string. It demonstrates how to add items to the Frequency
, sort by frequency and calculate a proportional amount.
// repl-pad
import { frequencyMutable } from "https://unpkg.com/ixfx/dist/data.js"
const freq = frequencyMutable();
const text = 'This is a test';
// Loop through all characters
for (let i = 0; i < text.length; i++) {
const letter = text.toLocaleUpperCase().charAt(i);
if (letter === ` `) continue; // Skip spaces;
freq.add(letter); // Add letter
}
// Sort with most frequent at position 0 of the array
const sorted = freq.entriesSorted(`valueReverse`);
// Grab just the top three
const topThree = sorted.slice(0, Math.min(sorted.length, 3));
// Calculate the min, max and avg over all frequencies
const mma = freq.minMaxAvg();
// Calculate percentage for a given letter
const percent = (kv) => Math.round(kv[1] / mma.total * 100);
const top = topThree[0];
console.log(`Letter ${top[0]} appears ${percent(top)}% of the time.`);