Overview

This tutorial explores how to compare standards from one framework to another to help so you can differentiate content by jurisdiction. This technique is known as standards crosswalks. Knowledge Graph does not yet have standards crosswalks data modeled, but there are steps you can take to understand how crosswalks will work in the future by utilizing LearningComponent and StandardsFrameworkItem entities and relationships to compare overlap across standards jurisdictions. Basically, it works like this:
Crosswalks Data Model Diagram High Level White Bg
Pn
This tutorial will walk you through the main concepts for comparing standards from one framework to another to build your intuition on the approach and start exploring how to apply this upcoming dataset to your product.

Key demonstrated capabilities

  • Unpacking standards into learning components
  • Using learning components to compare standards between different jurisdictions

Prerequisites

  • This tutorial assumes you’ve downloaded Knowledge Graph
  • You can use either Node or Python to go through this tutorial
  • If using Node
    • node 14+
    • dotenv
    • csv-parse
    • arquero
  • If using Python
    • python 3.9+
    • pandas
    • python-dotenv

Step 1: Setup

Load dependencies, env variables, and data

First set up the environment, constants, create helper functions, and finally load the data for the tutorial.
// Dependencies
const fs = require('fs');
const path = require('path');
const { parse } = require('csv-parse/sync');
require('dotenv').config();

// Constants
const TARGET_STANDARD_CODE = '6.RP.A.2';

// Environment setup
const dataDir = process.env.KG_DATA_PATH;
if (!dataDir) {
  console.error('❌ KG_DATA_PATH environment variable is not set.');
  process.exit(1);
}

// Helper functions
function loadCSV(filename) {
  try {
    const content = fs.readFileSync(path.join(dataDir, filename), 'utf8');
    return parse(content, { columns: true, skip_empty_lines: true });
  } catch (error) {
    console.error(`❌ Error loading CSV file ${filename}: ${error.message}`);
    throw error;
  }
}

function loadData(aq) {
  const allStandardsFrameworkItems = aq.from(loadCSV('StandardsFrameworkItem.csv'));
  const learningComponentsData = aq.from(loadCSV('LearningComponent.csv'));
  const relationshipsData = aq.from(loadCSV('Relationships.csv'));

  console.log('✅ Raw data loaded from KG CSV files');
  console.log({
    allStandardsFrameworkItems: allStandardsFrameworkItems.numRows(),
    learningComponentsData: learningComponentsData.numRows(),
    relationshipsData: relationshipsData.numRows()
  });

  // Filter standards for Multi-State (Common Core) and Texas Mathematics
  const standardsFrameworkItemsData = allStandardsFrameworkItems
    .filter(d => 
      d.academicSubject === 'Mathematics' &&
      (d.jurisdiction === 'Multi-State' || d.jurisdiction === 'Texas')
    );

  const ccCount = standardsFrameworkItemsData
    .filter(d => d.jurisdiction === 'Multi-State')
    .numRows();

  const txCount = standardsFrameworkItemsData
    .filter(d => d.jurisdiction === 'Texas')
    .numRows();

  console.log('✅ Data filtered for Multi-State and Texas Mathematics standards');
  console.log({
    filteredStandardsFrameworkItems: standardsFrameworkItemsData.numRows(),
    "Common Core (Multi-State)": ccCount,
    "Texas": txCount,
    learningComponentsData: learningComponentsData.numRows(),
    relationshipsData: relationshipsData.numRows()
  });

  if (ccCount === 0) {
    console.error('❌ No Common Core mathematics standards found');
    return null;
  }

  if (txCount === 0) {
    console.error('❌ No Texas mathematics standards found');
    return null;
  }

  return { standardsFrameworkItemsData, learningComponentsData, relationshipsData };
}
The loaded data from dataset files should look something like this:
{
  "filteredStandardsFrameworkItems": 2086,
  "Common Core (Multi-State)": 836,
  "Texas": 1250,
  "learningComponentsData": 2471,
  "relationshipsData": 481488
}

Step 2: Unpack a Common Core standard

Find standard 6.RP.A.2 from Common Core

Simply get a single standard’s data as a starting point. This standard’s ID will be leveraged later on for standards comparisons and finding the supporting learning components.
function findTargetStandard(standardsFrameworkItemsData) {
  const targetStandardTable = standardsFrameworkItemsData
    .params({ targetCode: TARGET_STANDARD_CODE })
    .filter(d => d.statementCode === targetCode &&
      d.jurisdiction === 'Multi-State');

  const targetStandard = targetStandardTable.object();

  if (!targetStandard || !targetStandard.statementCode) {
    console.log(`❌ Standard not found: ${TARGET_STANDARD_CODE}`);
    return null;
  }

  console.log(`✅ Found target standard: ${targetStandard.statementCode}`);
  console.log(targetStandardTable.select('caseIdentifierUUID', 'statementCode', 'description').objects());

  return targetStandard;
}
The data for the specific standard should look like this:
{
  "caseIdentifierUUID": "6b9d6aa3-d7cc-11e8-824f-0242ac160002",
  "statementCode": "6.RP.A.2",
  "description": "Understand the concept of a unit rate $\\frac{a}{b}$ associated with a ratio a:b with $b \\neq 0$, and use rate language in the context of a ratio relationship."
}

Unpack the learning components for the standard.

We’ll use these learning components later to connect to another state’s standard that shares an overlapping set of components.
function findSupportingLearningComponents(targetStandard, relationshipsData, learningComponentsData) {
  const supportingLCs = relationshipsData
    .params({ targetId: targetStandard.caseIdentifierUUID })
    .filter(d => d.relationshipType === 'supports' && d.targetEntityValue === targetId)
    .join(learningComponentsData, ['sourceEntityValue', 'identifier'])
    .select('sourceEntityValue', 'description_2')
    .rename({ sourceEntityValue: 'identifier', description_2: 'description' });

  console.log(`✅ Found ${supportingLCs.numRows()} supporting learning components:`);
  console.log(supportingLCs.objects());

  return supportingLCs;
}
The data for the learning components supporting the specified standard should look like this:
[
  {
    "identifier": "523d04e7-47d8-55c7-bc44-792f3e01bfda",
    "description": "Use rate language in the context of a ratio relationship"
  },
  // ...
]

Step 3: compare to Texas standards

Find Texas standards with matched learning components.

In this step we’re going to do two important things in order to ultimately compare the standards between Texas and Common Core. First we need to take all of the learning components supporting Common Core that we found in the previous step and use the supports relationship to find the supported Texas standards. Secondly, we’ll then find all the supporting learning components for those Texas standards, not only the ones that also support Common Core.
function findMatchedTexasStandards(aq, supportingLCs, relationshipsData, standardsFrameworkItemsData, learningComponentsData) {
  const lcIds = supportingLCs.array('identifier');

  // First, find which Texas standards have overlapping learning components
  const matchedStandardIds = relationshipsData
    .filter(d => d.relationshipType === 'supports')
    .filter(aq.escape(d => lcIds.includes(d.sourceEntityValue)))
    .join(standardsFrameworkItemsData, ['targetEntityValue', 'caseIdentifierUUID'])
    .filter(d => d.jurisdiction === 'Texas')
    .select('targetEntityValue')
    .dedupe('targetEntityValue')
    .array('targetEntityValue');

  // Then get ALL learning components for those matched standards
  const results = relationshipsData
    .filter(d => d.relationshipType === 'supports')
    .filter(aq.escape(d => matchedStandardIds.includes(d.targetEntityValue)))
    .join(standardsFrameworkItemsData, ['targetEntityValue', 'caseIdentifierUUID'])
    .filter(d => d.jurisdiction === 'Texas')
    .join(learningComponentsData, ['sourceEntityValue', 'identifier']);

  // Organize learning component descriptions and identifiers for each matched standard
  const finalResults = results
    .select('targetEntityKey', 'targetEntityValue', 'statementCode', 'description_2', 'identifier', 'description')
    .rename({
      targetEntityValue: 'caseIdentifierUUID',
      description_2: 'standardDescription',
      identifier: 'lc_identifier',
      description: 'lc_description'
    })
    .groupby('caseIdentifierUUID', 'statementCode', 'standardDescription')
    .rollup({
      lcDescription: d => aq.op.array_agg(d.lc_description),
      lcIdentifier: d => aq.op.array_agg(d.lc_identifier)
    })
    .objects();

  console.log(`✅ Found ${finalResults.length} Texas standards with shared learning components (lc):`);
  console.log(finalResults);

  return finalResults;
}
The matched standards and their supporting learning components will look like this:
[
  {
    "caseIdentifierUUID": "caf46dae-d04b-5d5e-90e9-d1e5aa77156e",
    "statementCode": "111.26.b.4.D",
    "standardDescription": "give examples of rates as the comparison by division of two quantities having different attributes, including rates as quotients;",
    "lcDescription": [
      "Identify real-world ratios and use them to determine unit rates",
      // ...
    ],
    "lcIdentifier": [
      "b9b94f31-b58b-5e26-9efe-680b167046ba",
      // ...
    ]
  },
  // ...
]
Now we can compile the previous steps and review the full overlap of the target Common Core standard to the matching Texas standards (in this example there is only one matching standard).
function displayComparisonResults(targetStandard, supportingLCs, matchedTexasStandards) {
  // Display the full comparison results between the target Common Core standard
  // and the matched Texas standards, including supporting learning components.

  // Calculate overlap with the target standard
  const supportingLCDescriptions = supportingLCs.array('description');
  const resultsWithOverlap = matchedTexasStandards.map(std => {
    const overlapCount = std.lcDescription.filter(lc =>
      supportingLCDescriptions.includes(lc)
    ).length;
    const totalTargetLCs = supportingLCDescriptions.length;

    return {
      ...std,
      overlapCount,
      totalTargetLCs,
      overlapRatio: `${overlapCount}/${totalTargetLCs}`
    };
  });

  console.log(`✅ Full comparison between Common Core standard ${targetStandard.statementCode} and matched Texas standards:`);
  console.log(`📋 TARGET STANDARD:`);
  console.log(`  Code: ${targetStandard.statementCode}`);
  console.log(`  Description: ${targetStandard.description}`);
  console.log(`  Supporting Learning Components (${supportingLCs.numRows()}):`);
  supportingLCs.objects().forEach((lc, i) => {
    console.log(`   • ${lc.description}`);
  });
  console.log('');

  resultsWithOverlap.forEach((match, i) => {
    console.log(`📋 MATCHED STANDARD #${i + 1}:`);
    console.log(`  Code: ${match.statementCode}`);
    console.log(`  Description: ${match.standardDescription}`);
    console.log(`  Supporting Learning Components (${match.lcDescription.length}) - Overlap: ${match.overlapRatio}:`);

    const supportingLCDescriptions = supportingLCs.array('description');
    match.lcDescription.forEach((lc, j) => {
      const isShared = supportingLCDescriptions.includes(lc);
      const emoji = isShared ? '➕' : '➖';
      console.log(`   ${emoji} ${lc || '(no description)'}`);
    });
    console.log('');
  });
}
The final output of the comparison will look like this:
📋 TARGET STANDARD:
  Code: 6.RP.A.2
  Description: Understand the concept of a unit rate $\frac{a}{b}$ associated with a ratio a:b with $b \neq 0$, and use rate language in the context of a ratio relationship.
  Supporting Learning Components (3):
   • Use rate language in the context of a ratio relationship
   • Identify real-world ratios and use them to determine unit rates
   • Write a ratio a:b as a unit rate a/b

📋 MATCHED STANDARD #1:
  Code: 111.26.b.4.D
  Description: give examples of rates as the comparison by division of two quantities having different attributes, including rates as quotients;
  Supporting Learning Components (2) - Overlap: 2/3:
   ➕ Identify real-world ratios and use them to determine unit rates
   ➕ Write a ratio a:b as a unit rate a/b

Step 4: putting it all together

Now let’s create a final function to run everything.
async function main() {
  const aq = await import('arquero');

  console.log('\n=== COMPARE STANDARDS TUTORIAL ===\n');

  console.log('🔄 Step 1: Loading data...');
  const { standardsFrameworkItemsData, learningComponentsData, relationshipsData } = loadData(aq);

  if (!standardsFrameworkItemsData) {
    console.log('❌ Failed to load and validate data.');
    return;
  }

  console.log('');
  console.log('');
  console.log('🔄 Step 2: "Unpack" a Common Core standard...');
  const targetStandard = findTargetStandard(standardsFrameworkItemsData);
  if (!targetStandard) {
    console.log('❌ Failed to find target standard.');
    return;
  }

  const supportingLCs = findSupportingLearningComponents(targetStandard, relationshipsData, learningComponentsData);

  console.log('');
  console.log('');
  console.log('🔄 Step 3: Compare to Texas standards...');
  const matchedTexasStandards = findMatchedTexasStandards(aq, supportingLCs, relationshipsData, standardsFrameworkItemsData, learningComponentsData);

  displayComparisonResults(targetStandard, supportingLCs, matchedTexasStandards);
}

main().catch(console.error);

Conclusion

In this tutorial you unpacked a Common Core standard, found its supporting learning components, and compared them to Texas standards with overlapping components. That gave you a concrete way to see how two different frameworks can be connected even before the official crosswalk dataset is available. From here, you can experiment with swapping in other standards or jurisdictions, running comparisons across multiple codes at once, or layering in curriculum data like lessons and assessments to see how overlap shows up in instructional materials.

Crosswalk dataset coming soon

In the coming months, we’ll release a state crosswalk dataset that links each state’s math standards to their closest matching Common Core (CCSS) standards (when a match exists). Once a state’s framework is aligned to our Learning Component (LC) superset, we can calculate how similar its standards are to those in other states. The key is overlap: the more LCs two standards share, the stronger their relationship. To move from theory to practice, we’ll apply quantitative thresholds that measure both how much overlap exists and whether it’s balanced or one-sided. This approach converts fuzzy judgments into clear, scalable rules. We’re also working with our collaborators at Achievement Network to fine-tune these thresholds, ensuring the crosswalk data is both high quality and reliable.