CDC COVID19 vaccination data across US counties​
​by Mads Bahrami
For some time, the CDC COVID- Data Tracker has had some nice visualization for vaccination across US counties, however, with no source data available. Recently, the source data becomes available. In this short computational essay, I showed how to transform that data into computable datasets in the Wolfram Language. This dataset can be very useful for epidemiological studies on COVID19.

FIPS

Wolfram Language has the FIPS code data of all US counties. However, the CDC vaccination dataset contains US territories, too. I could have simply drop them out; but decided to include them. Therefore, first I need to have a complete list of FIPS codes for US inland counties and territories.
Get list of FIPS for US and its territories:
In[]:=
dt0=SortBy[Rest@Import["https://www.nrcs.usda.gov/wps/portal/nrcs/detail/national/home/?cid=nrcs143_013697","Data"]〚2,2〛,First];
Pick the max FIPS code within US (to distinguish the US territories):
In[]:=
max=Max@ToExpression@EntityValue
all US counties
ADMINISTRATIVE DIVISIONS
,"FIPSCode";
Get FIPS and location of only US territories:
In[]:=
{fips,loc}=TakeDrop[Transpose[Select[dt0,#〚1〛>max&]],1];
Since US territories are reported in two-letter abbreviation, generate list of rules as code->entity:
In[]:=
repRules=ThreadRule{"AS","GU","MP","PR",Missing[],"VI"},
United States
COUNTRY

dependencies
;
Interpret corresponding regions of each FIPS:
In[]:=
regions=MapThread[If[#1"Unknown",Missing[],Nearest[EntityValue[#2["AdministrativeDivisions"],"Name","EntityAssociation"],#1<>", "<>#2["Name"]]〚1〛]&][loc/.repRules];
Create a list as {FIPS, Region, Country (US territory)}:
In[]:=
fipsUSTerritories=Transpose[{ToString/@fips〚1〛,regions,(loc/.repRules)〚-1〛}];
Association of county->state:
In[]:=
cntyState=KeyValueMap[Thread[Rule[#2,#1]]&]@EntityValue
all US states with District of Columbia
ADMINISTRATIVE DIVISIONS
,"Subdivisions","EntityAssociation"//Flatten//Association;
US inland FIPS:
In[]:=
fipsUSInland=KeyValueMap[{#2,#1,cntyState[#1]}&]@EntityValue
all US counties
ADMINISTRATIVE DIVISIONS
,"FIPSCode","EntityAssociation";
US inland and territories as {FIPS,region,state or county}:
In[]:=
fipsUS=Join[fipsUSInland,fipsUSTerritories];​​fipsUS//Dimensions
Out[]=
{3233,3}
Create an association as FIPS -> {FIPS,region,state or county} and add two regions that are not in the dataset:
In[]:=
fipsInfo=JoinGroupBy[fipsUS,First,First],<|"72069""72069",
Humacao, Puerto Rico
ADMINISTRATIVE DIVISION
,
Puerto Rico
COUNTRY
,"72039""72039",
Ciales, Puerto Rico
ADMINISTRATIVE DIVISION
,
Puerto Rico
COUNTRY
|>;

Transforming CDC vaccine data per US counties:

Get the CDC raw data as Dataset (replacement at the end is for Kusilvak Census Area, AK, old one to new one):
In[]:=
ds0=Import["https://data.cdc.gov/api/views/8xkx-amqh/rows.csv?accessType=DOWNLOAD",{"CSV","Dataset"},HeaderLines1]/.(2270:>2158);
A peak into 10 random rows of dataset:
In[]:=
ds0[RandomChoice[Range[Length[ds0]],10]]
Out[]=
Clean up the column tags:
In[]:=
ds1=With[{keys=Normal@Keys@ds0[1]},ds0[All,AssociationThread[StringJoin/@Capitalize/@StringSplit[keys,"_"],keys]]];
Group by FIPS and then apply
In[]:=
ds2=ds1[Select[#FIPS≠"UNK"&]][GroupBy["FIPS"]][KeyMap[fipsInfo[With[{fips=ToString[#]},If[StringLength[fips]<5,"0"<>fips,fips]]]&]];
Define a function for generating time series:
In[]:=
tsGenerator[dataset_]:=Module[{dt0,days,vectors},​​dt0=Transpose@Normal@Values@dataset;​​days=dt0〚1〛;​​vectors=dt0〚-9;;〛;AssociationThread[{"FullyVaccinatedPercent","VaccinatedPercent","VaccinatedPercent12Plus","VaccinatedPercent12PlusPercent","VaccinatedPercent18Plus","VaccinatedPercent18PlusPercent","VaccinatedPercent65Plus","VaccinatedPercent65PlusPercent","ProportionOfFullyVaccinatedPerFIPS"},TimeSeries[#,{days}]&/@vectors]​​]
Create time series:
In[]:=
ds3=ds2[All,tsGenerator];//AbsoluteTiming
Out[]=
{2458.04,Null}
Pick data with missing county, and create time series (added country for interpretation of MH):
In[]:=
ds4=ds1[Select[#FIPS=="UNK"&]][GroupBy["RecipState"]][All,tsGenerator][KeyMap[{Missing[],Missing[],Interpreter["USState"|"Country"][#]}&]];//AbsoluteTiming
Out[]=
{89.0086,Null}
Sanity checks:
In[]:=
Select[Normal@Keys@ds3,FreeQ[_Missing]]//Dimensions
Out[]=
{3224,3}
In[]:=
Length/@Normal[Keys[ds3]]//Tally
Out[]=
{{3,3224}}
In[]:=
ds=Join[ds3,ds4][KeyValueMap[<|AssociationThread[{"FIPS","AdminDivision","StateCountry"},#1],#2|>&]][SortBy["StateCountry"]];
A peak into 10 random rows of dataset:
In[]:=
ds[RandomChoice[Range[Length[ds]],10]]
Out[]=

Visualization

Get the data of all US counties and time series for % of fully vaccinated:
In[]:=
{counties,ts}=ds[Select[MatchQ[#AdminDivision,Entity["AdministrativeDivision",{_,_,"UnitedStates"}]]&]][All,{"AdminDivision","FullyVaccinatedPercent"}]//Values//Normal//Transpose;
Merge all time series into a TemporalData (extract data from that will be much easier, see geoViz):
In[]:=
td=TemporalData[ts];
In[]:=
values=td["ValueList"]/.x_ListConstantArray[Missing[],Length[x]]/;ContainsOnly[x,{0}];
Define colors and bins used in the visualization:
In[]:=
colors=Blend
,
(*
,
,
*),#&/@Range[0,1,1/7];​​bins={0,5,10,20,30,40,50};​​cfunc[x_]:=Which@@FlattenPrependRiffle[Join[x≤#&/@bins,{x>Last[bins]}],colors],MatchQ[x,_Missing],

Define the legend used based on colors and bins:
In[]:=
legend=BarLegend[{colors,MinMax[bins]},bins,LegendLayout"Column",LegendLabel"%FullyVaccinated",LegendMarkerSize200]
Out[]=
Get all days:
Geo-visualize counties with colors proportional to % of fully vaccinated population per county:
Geo-viz 4 days:
Note the missing data are gray areas.

GIF

Create geo-viz for all days (time-consuming step):
Export geo-viz as GIF:
Export geo-viz as locally, too: