Skip to content

Instantly share code, notes, and snippets.

@drkane
Last active December 29, 2015 09:08
Show Gist options
  • Save drkane/7647768 to your computer and use it in GitHub Desktop.
Save drkane/7647768 to your computer and use it in GitHub Desktop.
<!doctype html>
<html ng-app>
<head>
<title>Estimating confidence intervals for socio-demographic outputs</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<!--<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>-->
</head>
<body ng-controller="MainCtrl">
<div ng-init="setStandardError()" class="container">
<div class="page-header">
<h1>Estimating confidence intervals for socio-demographic outputs</h1>
</div>
<div class="row">
<div class="col-sm-6">
<form class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-12">
<label class="radio-inline">
<input type="radio" ng-model="level" ng-change="changeLevel()" value="person"> Person level estimates
</label>
<label class="radio-inline">
<input type="radio" ng-model="level" ng-change="changeLevel()" value="household"> Household level estimates
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">National population:</label>
<div class="col-sm-8">
<input type="number" class="form-control" ng-model="initial.population" ng-change="setStandardError()" placeholder="National population" value="56100000" disabled>
<span class="help-block">England and Wales</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Number of years of sample used:</label>
<div class="col-sm-8">
<select class="form-control" ng-model="initial.years" ng-change="setStandardError()">
<option value="1">1 - LA</option>
<option value="3" selected="selected">3 - LA / MSOA</option>
<option value="5">5 - MSOA / LSOA</option>
</select>
<span class="help-block">Input the number of years of survey sample to be combined - 1, 3 or 5. Generally LA level estimates would be based on 1 or 3 years of sample, MSOA 3 or 5 years and LSOA 5 years of sample combined</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">National sample size:</label>
<div class="col-sm-8">
<p class="form-control" disabled>{{ nationalSampleSize | number:0 }}<p>
<span class="help-block">Assuming <input type="number" ng-model="samplePC" ng-change="setStandardError()" value="4" class="input-sm" style="width: 65px;" min="0" max="100" step="0.1" />% sample every year</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Population size for area of interest:</label>
<div class="col-sm-8">
<input type="number" class="form-control" ng-model="initial.interestPopn" ng-change="setStandardError()" placeholder="Population size for area of interest" value="522432">
<span class="help-block">Input the total population size for the geographic area of interest.</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Number of people in the population with that characteristic:</label>
<div class="col-sm-8">
<input type="number" class="form-control" ng-model="initial.char" ng-change="setStandardError()" placeholder="People in the population with that characteristic" value="900">
<span class="help-block">Input the number of people within the population with the characteristic of interest.</span>
</div>
</div>
</form>
</div>
<div class="col-sm-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Results</h2>
</div>
<div class="panel-body">
<div class="alert alert-success" ng-if="isSignificant">
<strong>Congratulations!</strong> The 95% confidence interval for the result is less than 40% of the total.
</div>
<div class="alert alert-danger" ng-if="!isSignificant">
The 95% confidence interval for the result is greater than 40% of the total.
</div>
</div>
<table class="table">
<tr>
<td>Estimate of people with characteristic:</td>
<td><strong>{{initial.char | number:0}}</strong> (prevalence: <strong>{{ (prevalence) * 100 | number:2 }}</strong>%)</td>
</tr>
<tr>
<td>Estimated sample size in area:</td>
<td><strong>{{ areaSampleSize | number:0 }}</strong></td>
</tr>
<tr>
<td colspan="2"><h3>Precision of estimates</h3></td>
</tr>
<tr>
<td colspan="2">
95% confidence interval
</td>
</tr>
<tr>
<td style="padding-left:50px;">around estimate +/-</td>
<td><strong>{{ interval.around | number:0 }}</strong></td>
</tr>
<tr ng-class="{'success': isSignificant }">
<td style="padding-left:50px;">as a proportion of estimate +/-</td>
<td><strong>{{ interval.proportion * 100 | number:2 }}</strong>%</td>
</tr>
<tr>
<td>Lower bound:</td>
<td><strong>{{ bounds.lower.number | number:0 }}</strong> (<strong>{{ bounds.lower.proportion * 100 | number:2 }}</strong>%)</td>
</tr>
<tr>
<td>Upper bound:</td>
<td><strong>{{ bounds.upper.number | number:0 }}</strong> (<strong>{{ bounds.upper.proportion * 100 | number:2 }}</strong>%)</td>
</tr>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h2>Notes</h2>
<ol class="text-muted row">
<li class="col-sm-4">
<p>This spreadsheet illustrates the approach we have taken to provide an indication of the population sizes that could be estimated to a sufficient level of precision based on 1, 3 or 5 years of survey sample.</p>
<p>This approach assumes a selection of a sample of people from the total population based on a simple random sample approach and does not take into account the effects of clustering (see note 2). The figures used here are more precise than the indicative calculations used in the consultation report.</p>
</li>
<li class="col-sm-4">
<p>In practice an address based frame would be used to draw a sample of households which has implications for the precision of estimates that can be produced for topics that are clustered at the household level. Some socio demographic characteristics are highly clustered within a household, for example household members often share the same ethnic group.</p>
<p>The precision of estimates that can be produced for these more clustered characteristics will be reduced (i.e. estimates will have a wider confidence interval). It is assumed that the population size for the area of interest is a known, fixed total. Sampling variation in that total would reduce the precision of estimates.</p>
</li>
</ol>
</div>
</div>
</div>
<script type="text/javascript">
function MainCtrl($scope, $window) {
$scope.level = "person";
$scope.initial= {
population:56100000,
years:3,
interestPopn:522452,
char:900
}
$scope.samplePC = 4;
$scope.nationalSampleSize = 0;
$scope.areaSampleSize = 0;
$scope.prevalence = 0;
$scope.standardError = {
error: 0,
number: 0
}
$scope.interval = {
around: 0,
proportion: 0
}
$scope.bounds = {
lower: { number: 0, proportion: 0 },
upper: { number: 0, proportion: 0 }
}
$scope.isSignificant = false;
$scope.changeLevel = function() {
if($scope.level == 'household') {
$scope.initial.population = 23400000;
$scope.initial.interestPopn = 199296;
$scope.initial.years = 5;
$scope.initial.char = 141;
} else {
$scope.initial.population = 56100000;
$scope.initial.interestPopn = 522452;
$scope.initial.years = 3;
$scope.initial.char = 900;
}
$scope.setStandardError();
}
$scope.setStandardError = function () {
initial = $scope.initial;
$scope.prevalence = initial.char / initial.interestPopn;
$scope.nationalSampleSize = ( $scope.samplePC / 100 ) * initial.years * initial.population;
$scope.areaSampleSize = ($scope.nationalSampleSize / initial.population) * initial.interestPopn;
$scope.standardError.error = $window.Math.sqrt( ( 1 - $scope.nationalSampleSize / initial.population ) * $scope.prevalence * ( 1 - $scope.prevalence ) / ( $scope.areaSampleSize - 1 ) );
$scope.standardError.number = $scope.standardError.error * initial.interestPopn;
$scope.interval.around = 1.96 * $scope.standardError.number;
$scope.interval.proportion = $scope.interval.around / initial.char;
$scope.bounds.lower.number = $window.Math.max( initial.char - $scope.interval.around, 0);
$scope.bounds.upper.number = initial.char + $scope.interval.around;
$scope.bounds.lower.proportion = $scope.prevalence - 1.96 * $scope.standardError.error;
$scope.bounds.upper.proportion = $scope.prevalence + 1.96 * $scope.standardError.error;
if($scope.interval.proportion < 0.4 ){
$scope.isSignificant = true;
} else {
$scope.isSignificant = false;
}
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment