Calculate Weighted Mape in R

Calculate Weighted MAPE in R – Expert Guide and Calculator :root { –primary-color: #004a99; –success-color: #28a745; –background-color: #f8f9fa; –text-color: #333; –secondary-text-color: #666; –border-color: #ddd; –card-background: #fff; –shadow-color: rgba(0, 0, 0, 0.05); } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: var(–background-color); color: var(–text-color); line-height: 1.6; margin: 0; padding: 0; display: flex; justify-content: center; padding: 20px 0; } .container { max-width: 1000px; width: 100%; background-color: var(–card-background); border-radius: 8px; box-shadow: 0 4px 15px var(–shadow-color); overflow: hidden; margin: 20px; } header { background-color: var(–primary-color); color: white; padding: 20px; text-align: center; border-bottom: 3px solid var(–success-color); } header h1 { margin: 0; font-size: 2.2em; font-weight: 600; } main { padding: 30px; } .calculator-section, .article-section { margin-bottom: 40px; padding: 30px; background-color: var(–card-background); border-radius: 8px; box-shadow: 0 2px 10px var(–shadow-color); } h2, h3 { color: var(–primary-color); margin-top: 0; margin-bottom: 20px; border-bottom: 2px solid var(–primary-color); padding-bottom: 8px; } .input-group { margin-bottom: 20px; text-align: left; } .input-group label { display: block; margin-bottom: 8px; font-weight: bold; color: var(–primary-color); } .input-group input[type="number"], .input-group input[type="text"] { width: calc(100% – 24px); padding: 12px; border: 1px solid var(–border-color); border-radius: 4px; font-size: 1em; margin-bottom: 5px; transition: border-color 0.3s ease; } .input-group input:focus { border-color: var(–primary-color); outline: none; } .input-group .helper-text { font-size: 0.85em; color: var(–secondary-text-color); display: block; margin-top: 5px; } .error-message { color: #dc3545; font-size: 0.85em; margin-top: 5px; display: none; /* Hidden by default */ } .button-group { display: flex; gap: 10px; margin-top: 25px; flex-wrap: wrap; /* Allow buttons to wrap on smaller screens */ } .btn { padding: 12px 20px; border: none; border-radius: 5px; font-size: 1em; font-weight: bold; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; text-align: center; white-space: nowrap; /* Prevent button text from wrapping */ } .btn-calculate { background-color: var(–primary-color); color: white; } .btn-calculate:hover { background-color: #003366; transform: translateY(-2px); } .btn-reset { background-color: var(–secondary-text-color); color: white; } .btn-reset:hover { background-color: #555; transform: translateY(-2px); } .btn-copy { background-color: #6c757d; color: white; } .btn-copy:hover { background-color: #5a6268; transform: translateY(-2px); } #results-container { margin-top: 30px; padding: 25px; background-color: #e9ecef; border-radius: 8px; border: 1px solid #dee2e6; } #results-container h3 { margin-top: 0; color: var(–primary-color); border-bottom: none; } #primary-result { font-size: 2.5em; font-weight: bold; color: var(–primary-color); margin-bottom: 15px; display: block; text-align: center; background-color: #fff3cd; /* Light yellow for emphasis */ padding: 15px; border-radius: 6px; border: 1px solid #ffeeba; } .intermediate-results div, .assumption-item { margin-bottom: 10px; font-size: 1.1em; color: var(–secondary-text-color); } .intermediate-results strong, .assumption-item strong { color: var(–text-color); font-weight: 600; } .formula-explanation { font-size: 0.9em; color: var(–secondary-text-color); margin-top: 15px; padding-top: 10px; border-top: 1px dashed var(–border-color); } table { width: 100%; border-collapse: collapse; margin-top: 20px; box-shadow: 0 2px 5px var(–shadow-color); } th, td { padding: 12px 15px; text-align: right; border: 1px solid var(–border-color); } thead th { background-color: var(–primary-color); color: white; font-weight: bold; } tbody tr:nth-child(odd) { background-color: #f2f2f2; } caption { font-size: 0.9em; color: var(–secondary-text-color); margin-bottom: 10px; caption-side: top; text-align: left; font-style: italic; } #chart-container { margin-top: 30px; text-align: center; background-color: var(–card-background); padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px var(–shadow-color); } #chart-container canvas { max-width: 100%; height: auto !important; /* Ensure canvas scales */ } .chart-caption { font-size: 0.9em; color: var(–secondary-text-color); margin-top: 15px; display: block; } .article-section p, .article-section li { font-size: 1em; color: var(–text-color); margin-bottom: 15px; } .article-section ul, .article-section ol { padding-left: 25px; margin-bottom: 15px; } .article-section li { margin-bottom: 10px; } .article-section a { color: var(–primary-color); text-decoration: none; font-weight: bold; } .article-section a:hover { text-decoration: underline; } .faq-item { margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px dashed var(–border-color); } .faq-item:last-child { border-bottom: none; } .faq-question { font-weight: bold; color: var(–primary-color); cursor: pointer; display: block; margin-bottom: 5px; } .faq-answer { font-size: 0.95em; color: var(–secondary-text-color); display: none; /* Hidden by default */ padding-left: 10px; } .related-links ul { list-style: none; padding-left: 0; } .related-links li { margin-bottom: 15px; } footer { text-align: center; padding: 20px; font-size: 0.85em; color: var(–secondary-text-color); border-top: 1px solid var(–border-color); margin-top: 40px; } @media (max-width: 768px) { main { padding: 20px; } header h1 { font-size: 1.8em; } .btn-group { flex-direction: column; align-items: stretch; } .btn { width: 100%; } }

Calculate Weighted MAPE in R

Your Essential Tool for Forecasting Accuracy Evaluation

Weighted MAPE Calculator

Enter your historical actual data points, separated by commas.
Enter the corresponding forecasted values, separated by commas.
Enter the weight for each data point, separated by commas. Weights must sum to 1.

Results

MAPE:
WMAPE:
Weighted Sum of Absolute Errors:
Weighted Sum of Actuals:
Formula Used: WMAPE = Σ(Weightᵢ * |Actualᵢ – Forecastᵢ| / Actualᵢ) / Σ(Weightᵢ * Actualᵢ) * 100%
Alternatively, if Actualᵢ can be zero, a common approach is: WMAPE = Σ(Weightᵢ * |Actualᵢ – Forecastᵢ|) / Σ(Weightᵢ * Actualᵢ) * 100%. This calculator uses the latter form for robustness.

What is Weighted MAPE in R?

{primary_keyword} stands for Weighted Mean Absolute Percentage Error. It's a crucial metric in time series forecasting and general predictive modeling to evaluate the accuracy of forecasts. Unlike the standard Mean Absolute Percentage Error (MAPE), WMAPE incorporates specific weights for each data point, allowing you to prioritize certain periods or observations based on their importance. This makes it a more flexible and nuanced tool for assessing forecast performance, especially when not all forecast errors are equally significant. When working with data in R, implementing and understanding WMAPE is essential for robust model evaluation.

Who Should Use It:

  • Data scientists and analysts building forecasting models.
  • Business strategists evaluating sales, demand, or inventory forecasts.
  • Financial modelers predicting market trends or economic indicators.
  • Anyone needing to quantify forecast accuracy while acknowledging varying levels of importance for different data points.

Common Misconceptions:

  • WMAPE is always better than MAPE: Not necessarily. If all data points are equally important, standard MAPE might suffice. WMAPE adds complexity that is only beneficial when differential weighting is justified.
  • WMAPE can handle zero actual values: The standard MAPE formula has issues with zero actuals (division by zero). While WMAPE can mitigate this by adjusting the calculation or using alternative definitions, it's crucial to understand how your specific implementation handles such cases. This calculator uses a robust definition less prone to division by zero issues when actuals are non-zero.
  • Weights are arbitrary: Weights should be assigned based on business logic or statistical significance, not randomly. They represent the relative importance of each observation.

{primary_keyword} Formula and Mathematical Explanation

The Weighted Mean Absolute Percentage Error (WMAPE) provides a weighted average of the absolute percentage errors between actual and forecasted values. Its strength lies in its ability to assign different levels of importance to different observations.

The most common formula for WMAPE, particularly useful when actual values might be zero or very small, is:

WMAPE = Σi=1n (wi * |Ai – Fi|) / Σi=1n (wi * Ai) * 100%

Where:

  • Ai is the actual value for observation 'i'.
  • Fi is the forecasted value for observation 'i'.
  • wi is the weight assigned to observation 'i'.
  • |Ai – Fi| is the absolute error for observation 'i'.
  • Σ denotes summation over all 'n' observations.

Mathematical Breakdown:

  1. Calculate Absolute Error: For each data point 'i', find the absolute difference between the actual value (Ai) and the forecasted value (Fi): |Ai – Fi|.
  2. Calculate Weighted Absolute Error: Multiply the absolute error by its corresponding weight (wi): wi * |Ai – Fi|.
  3. Sum Weighted Absolute Errors: Sum these weighted absolute errors across all data points: Σ(wi * |Ai – Fi|). This forms the numerator.
  4. Calculate Weighted Actual Values: Multiply each actual value (Ai) by its weight (wi): wi * Ai.
  5. Sum Weighted Actual Values: Sum these weighted actual values across all data points: Σ(wi * Ai). This forms the denominator.
  6. Calculate WMAPE: Divide the sum of weighted absolute errors (from step 3) by the sum of weighted actual values (from step 5).
  7. Convert to Percentage: Multiply the result by 100 to express the WMAPE as a percentage.

Variable Explanations:

Variables in the WMAPE Formula
Variable Meaning Unit Typical Range
Ai Actual Value Data Unit (e.g., Units, Dollars, Count) Non-negative, depends on data
Fi Forecasted Value Data Unit Depends on model, often non-negative
wi Weight Unitless Typically 0 to 1; Sums to 1 across all observations
|Ai – Fi| Absolute Error Data Unit Non-negative
WMAPE Weighted Mean Absolute Percentage Error Percentage (%) 0% to ∞% (Lower is better)

Practical Examples (Real-World Use Cases)

Example 1: Retail Sales Forecasting

A retail company wants to evaluate its monthly sales forecast for a specific product line. They consider the most recent months more critical for inventory planning and thus assign higher weights to them.

  • Actual Sales (Units): 100, 110, 120, 130, 140
  • Forecasted Sales (Units): 105, 112, 125, 135, 142
  • Weights: 0.1, 0.15, 0.2, 0.25, 0.3 (Sum = 1.0)

Calculation Steps (Illustrative):

WMAPE Calculation Steps
MonthActual (A)Forecast (F)Weight (w)|A-F|w*|A-F|w*A
11001050.150.510.0
21101120.1520.316.5
31201250.251.024.0
41301350.2551.2532.5
51401420.320.642.0
Total1.03.65125.0

WMAPE = (3.65 / 125.0) * 100% = 2.92%

Interpretation: The weighted MAPE of 2.92% indicates a relatively accurate forecast, with errors in more recent, heavily weighted months having a significant impact on the overall metric.

Example 2: Demand Forecasting for a Pharmaceutical Product

A pharmaceutical distributor needs to forecast demand for a specific drug. Certain high-volume periods (e.g., flu season) are critical, and errors during these times are more costly. They assign weights reflecting this seasonality.

  • Actual Demand: 500, 600, 1200, 1500, 900
  • Forecasted Demand: 520, 610, 1150, 1550, 880
  • Weights: 0.1, 0.15, 0.35, 0.3, 0.1 (Sum = 1.0)

Calculation Steps (Illustrative):

WMAPE Calculation Steps
PeriodActual (A)Forecast (F)Weight (w)|A-F|w*|A-F|w*A
15005200.1202.050.0
26006100.15101.590.0
3120011500.355017.5420.0
4150015500.35015.0450.0
59008800.1202.090.0
Total1.038.01100.0

WMAPE = (38.0 / 1100.0) * 100% = 3.45%

Interpretation: A WMAPE of 3.45% suggests the forecasting model is performing reasonably well. The higher weights assigned to periods 3 and 4 (high demand) mean that errors during these critical times contributed more significantly to the overall WMAPE score.

How to Use This {primary_keyword} Calculator

Our interactive calculator simplifies the process of computing Weighted Mean Absolute Percentage Error in R or for any dataset. Follow these steps:

  1. Input Actual Values: In the "Actual Values" field, enter your historical observed data points. Separate each number with a comma. For example: 100, 110, 120.
  2. Input Forecast Values: In the "Forecast Values" field, enter the corresponding forecasted values for each actual data point. Ensure the number of forecast values matches the number of actual values. Example: 105, 112, 118.
  3. Input Weights: In the "Weights" field, enter the weight for each corresponding data point. These weights should reflect the relative importance of each observation. The weights must be numerical values and should ideally sum up to 1.0. Example: 0.2, 0.3, 0.5.
  4. Validate Inputs: The calculator will perform real-time checks. Look for error messages below each input field if values are missing, non-numeric, negative, or if the weights don't sum close to 1.
  5. Calculate WMAPE: Click the "Calculate WMAPE" button.

How to Read Results:

  • Primary Result (Highlighted): This is your main WMAPE score, displayed as a percentage. A lower percentage indicates a more accurate forecast.
  • Intermediate Values:
    • MAPE: The standard Mean Absolute Percentage Error is shown for comparison.
    • WMAPE: The calculated Weighted MAPE.
    • Weighted Sum of Absolute Errors: The numerator of the WMAPE formula.
    • Weighted Sum of Actuals: The denominator of the WMAPE formula.
  • Formula Explanation: Understand the exact calculation used.

Decision-Making Guidance:

  • Benchmarking: Compare the WMAPE score against historical model performance or industry benchmarks.
  • Model Selection: Use WMAPE, alongside other metrics, to compare different forecasting models. The model with the lower WMAPE might be preferred, especially if the weighting scheme accurately reflects business priorities.
  • Actionable Insights: Analyze periods with high percentage errors. Investigate why the forecast was off and whether the assigned weights correctly capture the cost of these errors. For instance, if WMAPE is high due to errors in critical peak demand periods, focus on improving forecasts for those times.
  • Iterative Improvement: Use the WMAPE metric to track improvements after refining your forecasting models or adjusting forecasting strategies.

Copy Results: Click "Copy Results" to easily transfer the calculated WMAPE, intermediate values, and key assumptions to your reports or analyses. This feature is invaluable for documentation and further investigation.

Reset: Use the "Reset" button to clear all inputs and results, allowing you to start a new calculation.

Key Factors That Affect {primary_keyword} Results

Several factors can significantly influence the Weighted MAPE calculation and its interpretation. Understanding these is key to using the metric effectively:

  1. Data Quality: Inaccurate or erroneous actual data will directly lead to incorrect error calculations and thus a flawed WMAPE. Ensure your historical data is clean and reliable.
  2. Forecast Accuracy: Fundamentally, the closer the forecast (Fi) is to the actual value (Ai), the lower the absolute error |Ai – Fi|, and consequently, the lower the WMAPE. This metric directly measures the magnitude of forecast errors.
  3. Weighting Scheme: This is the defining feature of WMAPE. The choice of weights (wi) dramatically impacts the final score. Assigning higher weights to more important periods (e.g., peak seasons, critical months) means errors in those periods will disproportionately increase the WMAPE. Conversely, low weights minimize the impact of errors in less critical times. A poorly chosen weighting scheme can be misleading.
  4. Scale of Actual Values: While WMAPE is a percentage error, the denominator (Σ wi * Ai) is based on the scale of the actual data. If actual values are very small, even small absolute errors can result in a high percentage error, especially if weights are not proportionally adjusted. Conversely, very large actual values might make the WMAPE appear small even if the absolute errors are substantial.
  5. Volatility and Seasonality: Highly volatile time series or those with strong seasonality can be challenging to forecast. Significant deviations during peak seasons or sudden demand shifts will increase forecast errors. The WMAPE will reflect these difficulties, and the assigned weights should account for the importance of capturing these patterns correctly.
  6. Outliers: Extreme values (outliers) in either actual or forecasted data can heavily influence the WMAPE. A single large error, especially if weighted heavily, can skew the metric significantly. It's important to investigate the cause of outliers and decide whether they should be included, transformed, or handled separately.
  7. Zero or Near-Zero Actual Values: While the formula used here is robust against division by zero (using weighted sum of actuals in the denominator), situations with zero actual values still require careful consideration. The concept of percentage error becomes less meaningful when the base value is zero. The weights and the specific WMAPE formula variant become critical in such scenarios.
  8. Forecast Horizon: Forecast accuracy typically decreases as the forecast horizon increases. WMAPE calculated over longer horizons will likely be higher than that calculated for shorter, more immediate periods.

Frequently Asked Questions (FAQ)

Q1: What is the difference between MAPE and WMAPE?
MAPE calculates the average of absolute percentage errors across all data points equally. WMAPE, on the other hand, allows you to assign different levels of importance (weights) to different data points, making it more flexible when not all errors are of equal consequence.
Q2: Can WMAPE be negative?
No, WMAPE cannot be negative. It's calculated using absolute errors, which are always non-negative. Therefore, the WMAPE will always be zero or positive. A WMAPE of 0% indicates a perfect forecast.
Q3: How should I choose the weights for WMAPE?
Weights should be chosen based on the business context and the relative importance of each data point. Common approaches include: assigning higher weights to recent data, periods of high demand, critical events, or data points with higher sales volume. Ensure the weights sum to 1.0 for easier interpretation.
Q4: What is a "good" WMAPE score?
There is no universal "good" WMAPE score. It depends heavily on the industry, the specific product/service, the forecasting model used, and the volatility of the data. Generally, lower is better. Compare your WMAPE to historical benchmarks or the performance of alternative models. A score below 5-10% might be considered good in many contexts, but this is highly variable.
Q5: How does WMAPE handle zero actual values?
The standard MAPE formula involves division by the actual value (Ai), which causes a division-by-zero error if Ai = 0. The WMAPE formula used in this calculator, WMAPE = Σ(wi * |Ai – Fi|) / Σ(wi * Ai) * 100%, avoids this issue as long as at least some weighted actuals are non-zero. However, if the denominator Σ(wi * Ai) is zero, the WMAPE is undefined. In practice, zero actuals often require special handling or alternative metrics.
Q6: Can I use WMAPE for evaluating forecasts of negative values?
WMAPE is typically used for non-negative quantities like sales, demand, or counts. If your data can be negative (e.g., profit margins), metrics like Mean Absolute Error (MAE) or Symmetric Mean Absolute Percentage Error (SMAPE) might be more appropriate, though SMAPE also has its own nuances with zero values. Always ensure the chosen metric aligns with the nature of the data.
Q7: What is the impact of outliers on WMAPE?
Outliers can have a significant impact, especially if they correspond to heavily weighted data points. A large absolute error (|Ai – Fi|) multiplied by its weight (wi) can substantially inflate the numerator. It's often advisable to investigate outliers and consider if they represent genuine extreme events or data errors.
Q8: Does R have a built-in function for WMAPE?
R doesn't have a single, universally standard built-in function specifically named `wMAPE`. However, you can easily calculate it using base R functions by implementing the formula described above, or by using packages like `Metrics` or `forecast` which might offer related functions or allow for custom implementations. Our calculator provides a direct way to compute it without needing R code.

Related Tools and Internal Resources

© 2023 Your Website Name. All rights reserved.

Disclaimer: This calculator and information are for educational and illustrative purposes only. Consult with a qualified professional for financial advice.

// — Calculator Logic — var chartInstance = null; // Global variable to hold chart instance function getFloatValue(id) { var value = parseFloat(document.getElementById(id).value.replace(/,/g, ")); return isNaN(value) ? null : value; } function getFloatArray(id) { var values = document.getElementById(id).value.split(',').map(function(item) { return parseFloat(item.trim()); }); // Check if any conversion resulted in NaN if (values.some(isNaN)) { return null; } return values; } function validateInputs() { var actuals = getFloatArray('actualValues'); var forecasts = getFloatArray('forecastValues'); var weights = getFloatArray('weights'); var errors = false; // Clear previous errors document.getElementById('actualValuesError').style.display = 'none'; document.getElementById('forecastValuesError').style.display = 'none'; document.getElementById('weightsError').style.display = 'none'; if (!actuals || actuals.length < 1) { document.getElementById('actualValuesError').innerText = 'Please enter valid actual values separated by commas.'; document.getElementById('actualValuesError').style.display = 'block'; errors = true; } if (!forecasts || forecasts.length < 1) { document.getElementById('forecastValuesError').innerText = 'Please enter valid forecast values separated by commas.'; document.getElementById('forecastValuesError').style.display = 'block'; errors = true; } if (!weights || weights.length < 1) { document.getElementById('weightsError').innerText = 'Please enter valid weights separated by commas.'; document.getElementById('weightsError').style.display = 'block'; errors = true; } if (actuals && forecasts && actuals.length !== forecasts.length) { document.getElementById('forecastValuesError').innerText = 'Number of actual values must match number of forecast values.'; document.getElementById('forecastValuesError').style.display = 'block'; errors = true; } if (actuals && weights && actuals.length !== weights.length) { document.getElementById('weightsError').innerText = 'Number of actual values must match number of weights.'; document.getElementById('weightsError').style.display = 'block'; errors = true; } if (actuals) { for (var i = 0; i < actuals.length; i++) { if (actuals[i] < 0) { document.getElementById('actualValuesError').innerText = 'Actual values cannot be negative.'; document.getElementById('actualValuesError').style.display = 'block'; errors = true; break; } if (forecasts && forecasts[i] < 0) { document.getElementById('forecastValuesError').innerText = 'Forecast values cannot be negative.'; document.getElementById('forecastValuesError').style.display = 'block'; errors = true; break; } if (weights[i] 0.0001) { // Allow for small floating point inaccuracies document.getElementById('weightsError').innerText = 'Weights should sum to approximately 1. Current sum: ' + sumWeights.toFixed(4); document.getElementById('weightsError').style.display = 'block'; // errors = true; // Decide if this should be a hard error or just a warning } } // Check for non-positive actuals in the denominator calculation basis if (actuals && weights) { var sumWeightedActualsForDenom = 0; for (var i = 0; i < actuals.length; i++) { if (actuals[i] <= 0) { // Using 0 } sumWeightedActualsForDenom += weights[i] * actuals[i]; } if (sumWeightedActualsForDenom <= 0) { // This indicates the denominator will be zero or negative, which is problematic document.getElementById('weightsError').innerText = 'The sum of (weight * actual value) must be positive.'; document.getElementById('weightsError').style.display = 'block'; errors = true; } } return !errors; } function calculateWMAPE() { if (!validateInputs()) { document.getElementById('primary-result').innerText = 'Error'; document.getElementById('mape-value').innerHTML = 'MAPE: Error'; document.getElementById('wmape-value').innerHTML = 'WMAPE: Error'; document.getElementById('weighted-sum-errors').innerHTML = 'Weighted Sum of Absolute Errors: Error'; document.getElementById('weighted-sum-actuals').innerHTML = 'Weighted Sum of Actuals: Error'; return; } var actuals = getFloatArray('actualValues'); var forecasts = getFloatArray('forecastValues'); var weights = getFloatArray('weights'); var n = actuals.length; var sumAbsError = 0; var sumMAPEError = 0; var sumWeightedActuals = 0; var countMAPE = 0; // Count for valid MAPE calculations for (var i = 0; i 0) { // Standard MAPE requires positive actuals sumMAPEError += (absError / actual); countMAPE++; } } var wmape = 0; if (sumWeightedActuals > 0) { wmape = (sumAbsError / sumWeightedActuals) * 100; } else if (sumAbsError === 0) { wmape = 0; // Perfect forecast with zero weighted actuals means WMAPE is 0 } else { wmape = Infinity; // Or some other indicator of error/undefined } var mape = 0; if (countMAPE > 0) { mape = (sumMAPEError / countMAPE) * 100; } else if (n > 0 && sumAbsError === 0) { // If all actuals were zero/non-positive but errors were zero mape = 0; } else { mape = Infinity; // Indicate error if no valid MAPE calculations possible } document.getElementById('primary-result').innerText = wmape.toFixed(2) + '%'; document.getElementById('wmape-value').innerHTML = 'WMAPE: ' + wmape.toFixed(2) + '%'; document.getElementById('mape-value').innerHTML = 'MAPE: ' + (mape === Infinity ? 'N/A' : mape.toFixed(2) + '%'); document.getElementById('weighted-sum-errors').innerHTML = 'Weighted Sum of Absolute Errors: ' + sumAbsError.toFixed(4); document.getElementById('weighted-sum-actuals').innerHTML = 'Weighted Sum of Actuals: ' + sumWeightedActuals.toFixed(4); updateChart(actuals, forecasts, weights); } function resetCalculator() { document.getElementById('actualValues').value = '100,110,120,130,140'; document.getElementById('forecastValues').value = '105,112,125,135,142'; document.getElementById('weights').value = '0.2,0.2,0.2,0.2,0.2'; // Clear errors document.getElementById('actualValuesError').style.display = 'none'; document.getElementById('forecastValuesError').style.display = 'none'; document.getElementById('weightsError').style.display = 'none'; // Reset results document.getElementById('primary-result').innerText = '–'; document.getElementById('mape-value').innerHTML = 'MAPE: –'; document.getElementById('wmape-value').innerHTML = 'WMAPE: –'; document.getElementById('weighted-sum-errors').innerHTML = 'Weighted Sum of Absolute Errors: –'; document.getElementById('weighted-sum-actuals').innerHTML = 'Weighted Sum of Actuals: –'; // Clear chart if (chartInstance) { chartInstance.destroy(); chartInstance = null; } var canvas = document.getElementById('accuracyChart'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas content canvas.width = canvas.width; // Reset canvas dimensions to clear it effectively } function copyResults() { var primaryResult = document.getElementById('primary-result').innerText; var mapeValue = document.getElementById('mape-value').innerText; var wmapeValue = document.getElementById('wmape-value').innerText; var weightedSumErrors = document.getElementById('weighted-sum-errors').innerText; var weightedSumActuals = document.getElementById('weighted-sum-actuals').innerText; var actuals = document.getElementById('actualValues').value; var forecasts = document.getElementById('forecastValues').value; var weights = document.getElementById('weights').value; var textToCopy = "WMAPE Calculation Results:\n\n"; textToCopy += "Primary WMAPE: " + primaryResult + "\n"; textToCopy += mapeValue + "\n"; textToCopy += wmapeValue + "\n"; textToCopy += weightedSumErrors + "\n"; textToCopy += weightedSumActuals + "\n\n"; textToCopy += "Inputs Used:\n"; textToCopy += "Actual Values: " + actuals + "\n"; textToCopy += "Forecast Values: " + forecasts + "\n"; textToCopy += "Weights: " + weights + "\n"; // Use a temporary textarea for copying var tempTextArea = document.createElement("textarea"); tempTextArea.value = textToCopy; tempTextArea.style.position = "absolute"; tempTextArea.style.left = "-9999px"; // Move outside the visible area document.body.appendChild(tempTextArea); tempTextArea.select(); try { document.execCommand("copy"); alert("Results copied to clipboard!"); } catch (e) { alert("Failed to copy results. Please copy manually."); } document.body.removeChild(tempTextArea); } // — Charting Logic — function updateChart(actuals, forecasts, weights) { var ctx = document.getElementById('accuracyChart').getContext('2d'); // Destroy previous chart instance if it exists if (chartInstance) { chartInstance.destroy(); } var n = actuals.length; var labels = []; for (var i = 1; i <= n; i++) { labels.push('Point ' + i); } // Calculate weighted average of actuals and forecasts for a representative line var weightedActualsData = []; var weightedForecastsData = []; var weightedErrorsData = []; // For a third series representing weighted error magnitude for (var i = 0; i < n; i++) { weightedActualsData.push(actuals[i] * weights[i]); weightedForecastsData.push(forecasts[i] * weights[i]); weightedErrorsData.push(Math.abs(actuals[i] – forecasts[i]) * weights[i]); } chartInstance = new Chart(ctx, { type: 'bar', // Use bar chart for individual points data: { labels: labels, datasets: [{ label: 'Weighted Actual Value', data: weightedActualsData, backgroundColor: 'rgba(0, 74, 153, 0.6)', // Primary color variation borderColor: 'rgba(0, 74, 153, 1)', borderWidth: 1, type: 'line', // Display as line fill: false, tension: 0.1 }, { label: 'Weighted Forecast Value', data: weightedForecastsData, backgroundColor: 'rgba(40, 167, 69, 0.6)', // Success color variation borderColor: 'rgba(40, 167, 69, 1)', borderWidth: 1, type: 'line', // Display as line fill: false, tension: 0.1 }, { label: 'Weighted Absolute Error', data: weightedErrorsData, backgroundColor: 'rgba(255, 193, 7, 0.7)', // Warning color borderColor: 'rgba(255, 193, 7, 1)', borderWidth: 1, type: 'bar' // Display error as bars }] }, options: { responsive: true, maintainAspectRatio: false, // Allows custom height scales: { y: { beginAtZero: true, title: { display: true, text: 'Value / Error Magnitude' } }, x: { title: { display: true, text: 'Data Points' } } }, plugins: { title: { display: true, text: 'Weighted Values vs. Weighted Errors', font: { size: 16 } }, legend: { position: 'top', } } } }); } // Initial chart drawing with default values if they exist document.addEventListener('DOMContentLoaded', function() { // Attempt to calculate with initial default values on load // Ensure validateInputs passes for defaults before calculateWMAPE is called var defaultsValid = true; try { // Temporarily set values to defaults for validation check var tempActuals = '100,110,120,130,140'.split(',').map(parseFloat); var tempForecasts = '105,112,125,135,142'.split(',').map(parseFloat); var tempWeights = '0.2,0.2,0.2,0.2,0.2'.split(',').map(parseFloat); if(tempActuals.some(isNaN) || tempForecasts.some(isNaN) || tempWeights.some(isNaN)){ defaultsValid = false; } // A more robust check could involve simulating validateInputs, but for initial render, basic check is usually fine. } catch (e) { defaultsValid = false; } if (defaultsValid) { calculateWMAPE(); } else { // Clear or show placeholder chart if defaults are invalid var canvas = document.getElementById('accuracyChart'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); } // Add event listeners for input changes to trigger updates dynamically document.getElementById('actualValues').addEventListener('input', calculateWMAPE); document.getElementById('forecastValues').addEventListener('input', calculateWMAPE); document.getElementById('weights').addEventListener('input', calculateWMAPE); }); // FAQ Toggle Functionality function toggleFaq(element) { var answer = element.nextElementSibling; if (answer.style.display === "block") { answer.style.display = "none"; } else { answer.style.display = "block"; } }

Forecast Accuracy Visualization

This chart displays the weighted actual values, weighted forecasted values, and the magnitude of weighted absolute errors for each data point. Compare the lines to visualize forecast fit and the bars to see the contribution of error at each point, weighted by importance.

Leave a Comment