Hitter Projection Calculator: wRC+ and Weighted On-Base Average (wOBA)

ANALife Services AuthorityNational Calculator Authority›Hitter Projection Calculator: wRC+ and Weighted On-Base Average (wOBA)

.calc-container { max-width: 640px; margin: 2rem 0; padding: 1.5rem; background: #fff; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); font-family: system-ui, -apple-system, sans-serif; } .calc-container h3 { font-family: Georgia, serif; font-size: 1.15rem; color: #1a1a1a; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; flex-wrap: wrap; } .calc-row label { min-width: 160px; font-size: 0.9rem; color: #333; font-weight: 500; } .calc-row input[type="number"], .calc-row select { flex: 1; min-width: 120px; max-width: 200px; padding: 0.5rem 0.6rem; border: 1px solid #ccc; border-radius: 4px; font-size: 0.9rem; font-family: system-ui, sans-serif; color: #1a1a1a; background: #fafaf8; } .calc-row input:focus, .calc-row select:focus { outline: none; border-color: var(--ac, #3d5a80); box-shadow: 0 0 0 2px rgba(26,74,138,0.12); } .calc-row .unit { font-size: 0.82rem; color: #888; min-width: 30px; } .calc-btn { display: inline-block; margin-top: 0.5rem; padding: 0.55rem 1.5rem; background: var(--ac, #3d5a80); color: #fff; border: none; border-radius: 4px; font-size: 0.9rem; font-weight: 600; cursor: pointer; font-family: system-ui, sans-serif; } .calc-btn:hover { opacity: 0.9; } .calc-result { margin-top: 1.25rem; padding: 1rem 1.25rem; background: #f0f6fc; border-left: 3px solid var(--ac, #3d5a80); border-radius: 0 6px 6px 0; display: none; } .calc-result.visible { display: block; } .calc-result-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: #666; margin-bottom: 0.25rem; } .calc-result-value { font-size: 1.6rem; font-weight: 700; color: var(--ac, #3d5a80); } .calc-result-detail { font-size: 0.85rem; color: #555; margin-top: 0.5rem; line-height: 1.5; } .calc-note { margin-top: 1rem; font-size: 0.8rem; color: #888; font-style: italic; } .calc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-top: 0.75rem; } .calc-grid-item { padding: 0.6rem 0.8rem; background: #f8f9fa; border-radius: 4px; border: 1px solid #eee; } .calc-grid-item .label { font-size: 0.75rem; color: #888; text-transform: uppercase; letter-spacing: 0.04em; } .calc-grid-item .value { font-size: 1.1rem; font-weight: 600; color: #1a1a1a; } @media (max-width: 720px) { .calc-row { flex-direction: column; align-items: flex-start; gap: 0.3rem; } .calc-row label { min-width: auto; } .calc-row input[type="number"], .calc-row select { max-width: 100%; width: 100%; } .calc-grid { grid-template-columns: 1fr; } } .calc-chart { margin: 1rem 0; text-align: center; } .calc-chart svg { max-width: 100%; height: auto; } .calc-chart-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem 1.2rem; margin-top: 0.6rem; font-size: 0.8rem; color: #555; } .calc-chart-legend span { display: inline-flex; align-items: center; gap: 0.3rem; } .calc-chart-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; font-style: normal; } .calc-related { max-width: 640px; margin: 2rem 0 1rem; padding: 1.25rem 1.5rem; background: #f8f9fa; border: 1px solid #e8e8e8; border-radius: 8px; } .calc-related h3 { font-family: Georgia, serif; font-size: 1rem; color: #1a1a1a; margin: 0 0 0.75rem; padding-bottom: 0.4rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-related-list { list-style: none; padding: 0; margin: 0 0 0.75rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 1.5rem; } .calc-related-list li a { font-size: 0.88rem; color: var(--ac, #3d5a80); text-decoration: none; } .calc-related-list li a:hover { text-decoration: underline; } .calc-browse-all { margin: 0.5rem 0 0; font-size: 0.9rem; font-weight: 600; } .calc-browse-all a { color: var(--ac, #3d5a80); text-decoration: none; } .calc-browse-all a:hover { text-decoration: underline; } @media (max-width: 720px) { .calc-related-list { grid-template-columns: 1fr; } }

Hitter Projection Calculator: wRC+ and Weighted On-Base Average (wOBA)

Project a hitter's Weighted On-Base Average (wOBA) and park/league-adjusted Weighted Runs Created Plus (wRC+) using FanGraphs-style linear weights. Enter your hitter's counting stats and league context below.

### Plate Appearance Breakdown

Walks (BB)

Hit By Pitch (HBP)

Singles (1B)

Doubles (2B)

Triples (3B)

Home Runs (HR)

At Bats (AB)

Sacrifice Flies (SF)

Intentional BB (IBB)

### League Context

League wOBA

League OBP

wOBA Scale (R/PA)

League R/PA

Park Factor (100 = neutral)

Calculate wOBA & wRC+ Fill in the fields above and click Calculate.

function hitCalc() { // --- Read inputs --- var bb = parseFloat(document.getElementById('hit-bb').value) || 0; var hbp = parseFloat(document.getElementById('hit-hbp').value) || 0; var s1b = parseFloat(document.getElementById('hit-1b').value) || 0; var d2b = parseFloat(document.getElementById('hit-2b').value) || 0; var t3b = parseFloat(document.getElementById('hit-3b').value) || 0; var hr = parseFloat(document.getElementById('hit-hr').value) || 0; var ab = parseFloat(document.getElementById('hit-ab').value) || 0; var sf = parseFloat(document.getElementById('hit-sf').value) || 0; var ibb = parseFloat(document.getElementById('hit-ibb').value) || 0; var lgWOBA = parseFloat(document.getElementById('hit-lg-woba').value) || 0.320; var lgOBP = parseFloat(document.getElementById('hit-lg-obp').value) || 0.318; var wobaScale = parseFloat(document.getElementById('hit-woba-scale').value) || 1.157; var lgRPA = parseFloat(document.getElementById('hit-lg-r-pa').value) || 0.1150; var parkFactor= parseFloat(document.getElementById('hit-park').value) || 100;

var res = document.getElementById('hit-result');

// --- Validation --- var errors = []; if (ab 0.450) errors.push("League wOBA should be between 0.200 and 0.450."); if (lgOBP 0.450) errors.push("League OBP should be between 0.200 and 0.450."); if (wobaScale 2.0) errors.push("wOBA Scale should be between 1.000 and 2.000."); if (lgRPA 0.20) errors.push("League R/PA should be between 0.05 and 0.20."); if (parkFactor 150) errors.push("Park Factor should be between 50 and 150.");

// Logical cross-checks var hits = s1b + d2b + t3b + hr; var pa = ab + bb + hbp + sf; if (pa ab) errors.push("Total hits cannot exceed At Bats."); if (ibb > bb) errors.push("Intentional BB cannot exceed total Walks.");

if (errors.length > 0) { res.innerHTML = 'Please fix the following:' + errors.map(function(e){ return ''; }).join('') + ''; return; }

// --- FanGraphs 2023 linear weights (standard season) --- // Source: FanGraphs guts page (approximate 2022-2023 values) var w_bb = 0.690; var w_hbp = 0.722; var w_1b = 0.888; var w_2b = 1.271; var w_3b = 1.616; var w_hr = 2.101;

// --- wOBA numerator --- var woba_num = (w_bb * (bb - ibb)) + (w_hbp * hbp) + (w_1b * s1b) + (w_2b * d2b) + (w_3b * t3b) + (w_hr * hr);

// --- wOBA denominator: AB + BB - IBB + SF + HBP --- var woba_den = ab + (bb - ibb) + sf + hbp;

if (woba_den Denominator for wOBA is zero. Check your inputs.'; return; }

var woba = woba_num / woba_den;

// --- wRAA (Weighted Runs Above Average) --- // wRAA = ((wOBA - lgwOBA) / wOBAScale) * PA var wraa = ((woba - lgWOBA) / wobaScale) * pa;

// --- wRC (Weighted Runs Created) --- // wRC = wRAA + (lgR/PA * PA) var wrc = wraa + (lgRPA * pa);

// --- wRC+ --- // wRC+ = ( (wRAA/PA + lgR/PA) + (lgR/PA - PF * lgR/PA) ) / lgR/PA * 100 // Simplified: wRC+ = 100 * ( (wOBA - lgwOBA)/wOBAScale + lgR/PA ) / (lgR/PA * PF/100) var pf = parkFactor / 100.0; var wrcPlus = 100 * ( ((woba - lgWOBA) / wobaScale) + lgRPA ) / (lgRPA * pf);

// --- OBP for reference --- var obp = (hits + bb + hbp) / (ab + bb + hbp + sf);

// --- Slugging --- var slg = (s1b + 2d2b + 3t3b + 4*hr) / ab;

// --- OPS --- var ops = obp + slg;

// --- Rating labels --- function wobaRating(w) { if (w >= 0.400) return "Elite"; if (w >= 0.370) return "Great"; if (w >= 0.340) return "Above Average"; if (w >= 0.310) return "Average"; if (w >= 0.280) return "Below Average"; if (w >= 0.250) return "Poor"; return "Very Poor"; } function wrcPlusRating(w) { if (w >= 160) return "Elite"; if (w >= 140) return "Great"; if (w >= 115) return "Above Average"; if (w >= 95) return "Average"; if (w >= 80) return "Below Average"; if (w >= 65) return "Poor"; return "Very Poor"; }

var wobaR = wobaRating(woba); var wrcPlusR = wrcPlusRating(wrcPlus);

res.innerHTML = '### Results ' + '' + 'MetricValueRating' + 'wOBA' + woba.toFixed(3) + '' + wobaR + '' + 'wRC+' + wrcPlus.toFixed(1) + '' + wrcPlusR + '' + 'wRAA' + wraa.toFixed(1) + ' runs' + 'wRC' + wrc.toFixed(1) + ' runs' + 'OBP' + obp.toFixed(3) + '' + 'SLG' + slg.toFixed(3) + '' + 'OPS' + ops.toFixed(3) + '' + 'Plate Appearances' + pa.toFixed(0) + '' + ''; }

#### Formulas Used

wOBA (Weighted On-Base Average):

wOBA = (0.690×uBB + 0.722×HBP + 0.888×1B + 1.271×2B + 1.616×3B + 2.101×HR) ───────────────────────────────────────────────────────────────────────── AB + uBB + SF + HBP

where uBB = BB − IBB (unintentional walks)

wRAA (Weighted Runs Above Average):

wRAA = ((wOBA − lgwOBA) / wOBAScale) × PA

wRC (Weighted Runs Created):

wRC = wRAA + (lgR/PA × PA)

wRC+ (Park & League Adjusted):

wRC+ = 100 × [ ((wOBA − lgwOBA) / wOBAScale) + lgR/PA ] ───────────────────────────────────────── lgR/PA × ParkFactor

wRC+ = 100 means exactly league average. Every point above/below 100 is one percentage point better/worse than league average, park-adjusted.

#### Assumptions & References

More Calculators

Read Next

Study Time Planner Authority Network America › Life Services Authority › National Calculator Authority .calc-container { max-width: 640px;...

References