Ravindra BagaleCourses & study guides मराठी Track your progress

Guides

Case Study: NYC Restaurant Inspections in Excel (Real NYC Open Data)

A restaurant group is opening its next place in New York City and wants to pass its first health inspection. The operations manager asks: "How many restaurants score in the A range at their first inspection, and what do inspectors cite most?" We downloaded every initial cycle inspection from April to June 2026. Only 56.9% of 3,920 inspections scored 0 to 13 points, the A range, and one maintenance violation (code 10F) appeared in 55.5% of inspections.

Download the DOHMH Restaurant Inspection Results from NYC Open Data, filter to one inspection type and period, remove duplicates and rows with a missing borough, then build one row per inspection with a key (CAMIS and date), XLOOKUP for borough, cuisine and score, and COUNTIFS for violations. Compare boroughs and cuisines with COUNTIFS and AVERAGEIFS, rank violation codes with COUNTIF, and chart the results.

Real data on this page

This case study uses real public data from NYC Open Data (Department of Health and Mental Hygiene), not fictional teaching data. It is the one exception to the fictional-data rule on this site. Every number on this page was calculated from the downloaded extract, and the practice workbook contains the same rows and formulas so you can check each one.

Download the practice file (case-study-nyc-restaurant-inspections.xlsx)

Excel file, 1291 KB. It holds the trimmed real data and every formula used below. It has every downloaded violation row for the quarter (minus the removed rows, which are kept on their own sheet), the inspection table built with formulas, the analysis and the dashboard.

Quick answer

  1. Open the DOHMH New York City Restaurant Inspection Results dataset on NYC Open Data and filter Inspection Type to Cycle Inspection / Initial Inspection and the dates you want.
  2. Export to CSV, remove exact duplicates and rows with borough 0.
  3. Add a Key column: CAMIS and inspection date joined, because each violation is a separate row.
  4. Make one row per inspection and fill it with XLOOKUP (borough, cuisine, score) and COUNTIFS (violations, critical violations).
  5. Use COUNTIFS and AVERAGEIFS for the A-range share and average score by borough and cuisine, and COUNTIF to rank violation codes.
  6. Chart the results on a Dashboard sheet and write the recommendation.

The business question

NYC inspectors give points for each violation. Fewer points is better. NYC Health's letter grading page says: 0 to 13 points is an A, 14 to 27 is a B, and 28 or more is a C. A new restaurant wants to know its odds and where to focus its training. So the questions are:

  1. What share of initial inspections score in the A range (0 to 13)?
  2. Does it differ by borough or by type of cuisine?
  3. Which violations come up most often, so staff can be trained for them?

The data: source and licence

Source and licence

Dataset: *DOHMH New York City Restaurant Inspection Results*, published by the NYC Department of Health and Mental Hygiene on NYC Open Data (dataset id 43nn-pn8j), updated daily. We used the extract with record date 5 October 2026.

Where: data.cityofnewyork.us/.../43nn-pn8j. Downloaded 6 October 2026 through the dataset's API with the filter Inspection Type = 'Cycle Inspection / Initial Inspection' and inspection date 1 April to 30 June 2026.

Licence and terms: NYC's Open Data Law (Local Law 11 of 2012) makes City data available without registration, licence requirements or restrictions on use. The NYC Open Data terms of use say the data is provided as is. As the City asks, we name the source, the version (extract date) and our changes, and note that the City of New York cannot vouch for the accuracy or completeness of the data or of this analysis.

Our changes: we kept 14 columns (restaurant name, address, phone and map columns left out, because this lesson compares groups, not named businesses), removed 9 exact duplicate rows and 15 rows whose borough is coded 0, and built the inspection table and analysis. The removed rows are on their own sheet in the practice file.

Grades: the score bands come from NYC Health: Letter Grading for Restaurants.

ColumnMeaning
CAMISUnique number for each restaurant (per permit)
BoroBorough
Inspection dateDate of the inspection
Violation code / descriptionOne row per violation cited
Critical flagCritical violations are those most likely to contribute to food-borne illness
ScoreTotal points for the inspection, repeated on every row of that inspection
GradeA, B, C, N (not yet graded), Z or P (grade pending); blank when no grade was issued

Step 1: Clean the rows

The key thing to understand: one row is one violation, not one inspection. An inspection with five violations has five rows, each repeating the score. Counting rows would count violations.

  1. Load the CSV with Data > From Text/CSV and click Load To > Table.
  2. Run Data > Remove Duplicates with all columns ticked.
  3. Filter Boro for 0 and delete those rows (the borough is missing).
  4. Add a Key column that names each inspection: =A2&"-"&TEXT(E2,"yyyymmdd") joins CAMIS and the date.
Cleaning stepRows leftRemoved
Violation rows downloaded (initial cycle inspections, Q2 2026)13,784
Remove exact duplicate rows13,7759
Remove rows with borough coded 0 (missing)13,76015

After cleaning there are 3,920 inspections at 3,917 restaurants (three restaurants had two initial inspections in the quarter). 11 inspections had no violations at all.

Step 2: One row per inspection

Copy the Key, CAMIS and date columns to a new sheet, run Remove Duplicates, make it a table called Inspections, and fill the other columns with formulas:

Boro           =XLOOKUP(C2,Violations[Key],Violations[Boro])
Score          =XLOOKUP(C2,Violations[Key],Violations[Score])
Grade          =XLOOKUP(C2,Violations[Key],Violations[Grade])&""
Violations     =COUNTIFS(Violations[Key],C2,Violations[Violation code],"<>")
Critical       =COUNTIFS(Violations[Key],C2,Violations[Critical flag],"Critical")
A-range score  =IF(F2<=13,"Yes","No")

XLOOKUP returns the first matching row, which is fine because the score is the same on every row of an inspection. The &"" turns an empty grade into empty text instead of 0.

Grade is not the same as score

Only an A is posted straight after an initial inspection; other restaurants are re-inspected before they get a letter. So in this data 2,198 inspections show grade A and 1,620 show no grade. To compare all restaurants fairly, we use the score (0 to 13 = A range), not the grade column.

Step 3: Compare boroughs and cuisines

  1. Insert a PivotTable from Inspections: Boro in Rows, Key in Values (Count), A-range score in Columns, then Show Values As > % of Row Total.
  2. For a report that stays put, use formulas: =COUNTIFS(Inspections[Boro],A3,Inspections[A-range score],"Yes")/B3 and =AVERAGEIFS(Inspections[Score],Inspections[Boro],A3).
  3. Do the same by Cuisine, keeping only cuisines with at least 100 inspections so that small groups do not mislead.
BoroughInspectionsA-range shareAvg scoreClosuresCritical per inspection
Bronx33455.4%19.572.04
Brooklyn1,02458.7%18.0161.91
Manhattan1,54258.6%17.8141.93
Queens87252.3%20.0122.15
Staten Island14858.1%16.511.91
All boroughs3,92056.9%18.5501.98

The median score is 13, exactly the top of the A range, so a typical restaurant is one violation away from missing it. Brooklyn had the highest A-range share (58.7%) and Queens the lowest (52.3%). The gap between boroughs is small next to the gap between cuisines:

Cuisine (100+ inspections)InspectionsA-range shareAvg score
Donuts11279.5%11.4
Coffee/Tea31669.6%14.1
Mexican15862.0%17.1
Chicken12361.8%16.8
American67861.4%17.1
Pizza23954.8%17.7
Italian15453.9%19.3
Japanese13552.6%20.2
Bakery Products/Desserts15551.0%20.0
Chinese28548.4%21.1
Latin American16741.9%22.1
Caribbean12836.7%26.4

Careful with cuisine comparisons

Cuisines differ in menu, cooking steps and kitchen size. A low share does not mean a cuisine is unsafe; it means those kitchens get more points on average in this quarter.

Step 4: Rank the violations

Count each code with =COUNTIF(Violations[Violation code],H3) and divide by the number of inspections. No inspection had the same code twice, so this is also the share of inspections that got that violation.

CodeCitationsShare of inspectionsCritical?Description (shortened)
10F2,17455.5%Not CriticalNon-food contact surface or equipment made of unacceptable material, not kept clean, or not properly sealed, raised, spaced or movable ...
02G1,14429.2%CriticalCold TCS food item held above 41 °F; smoked or processed fish held above 38 °F; intact raw eggs held above 45 °F; or reduced oxygen ...
06D1,09828.0%CriticalFood contact surface not properly washed, rinsed and sanitized after each use and following any activity when contamination may have ...
06C1,01525.9%CriticalFood, supplies, or equipment not protected from potential source of contamination during storage, preparation, transportation, display, ...
08A98125.0%Not CriticalEstablishment is not free of harborage or conditions conducive to rodents, insects or other pests.
10B93823.9%Not CriticalAnti-siphonage or back-flow prevention device not provided where required; equipment or floor not properly drained; sewage disposal ...
02B81620.8%CriticalHot TCS food item not held at or above 140 °F.
04L58715.0%CriticalEvidence of mice or live mice in establishment's food or non-food areas.
10G42110.7%Not CriticalDishwashing and ware washing: Cleaning and sanitizing of tableware, including dishes, utensils, and equipment deficient.
05D3238.2%CriticalNo hand washing facility in or adjacent to toilet room or within 25 feet of a food preparation, food service or ware washing area. Hand ...

Step 5: Build the dashboard

  1. On the Dashboard sheet add six KPI cards that link to the Analysis sheet: inspections, A-range share, average score, closures, critical violations per inspection and the top violation's share.
  2. Insert a column chart of A-range share by borough and one of inspections by score band.
  3. Insert bar charts of the top 10 violation codes and of A-range share by cuisine.
  4. Turn off gridlines, align the charts and set landscape, fit to one page.

Dashboard sheet of the NYC restaurant inspections case study: KPI cards and charts for boroughs, score bands, violations and cuisines

The Dashboard sheet of the practice workbook (real data: NYC DOHMH via NYC Open Data).

Step 6: The recommendation

  1. Fix the cheap, common items first. Code 10F (non-food surfaces and equipment not clean or not properly sealed or movable) was cited in 55.5% of inspections. A deep clean and an equipment check before opening costs little.
  2. Make food temperature a daily checklist. Cold food held too warm (02G) appeared in 29.2% of inspections and hot food held too cool (02B) in 20.8%. Both are critical violations. Thermometers and a logged check twice per shift address both.
  3. Book pest control before the first inspection. Conditions that attract pests (08A) appeared in 25.0% of inspections and evidence of mice (04L) in 15.0%.
  4. Plan for a re-inspection anyway. Only 56.9% of initial inspections scored in the A range across the city, and 50 of 3,920 ended with the restaurant closed by DOHMH. Keep the team on the checklist until the grade card is posted.

What this data cannot tell you

  • It covers restaurants that were active on the extract date. Places that closed after their inspection are not in it.
  • Scores can change after a hearing; the dataset says scores are updated based on adjudication results. Re-download before you present.
  • Three months is a short window, and a borough or cuisine figure can move from quarter to quarter.

Ravindra Bagale's Tip

When a dataset has one row per event inside a bigger thing (violations inside inspections, lines inside invoices), build a Key column first and make a second table with one row per bigger thing. Most counting mistakes come from skipping this step.

Practice task

  1. On Violations, filter Key for one inspection with several rows and check that the Inspections sheet counts them correctly.
  2. Add a column to Inspections that shows the score band (A range, B range, C range) with IFS.
  3. Make a PivotTable of Inspections by Cuisine and Boro. Which cuisine has the lowest average score in Queens?
  4. Find how many inspections cited code 04L (mice) in each borough with COUNTIFS on the Violations sheet and the Key.
  5. Download the next quarter from NYC Open Data with the same filter and compare the A-range share.

Frequently asked questions

Can I use NYC Open Data in my own work?

Yes. NYC's Open Data Law makes the data available without registration, licence requirements or restrictions on use. Name the source, the version or download date and your changes, and do not suggest the City endorses your analysis.

Why does the grade column have so many blanks?

After an initial inspection, only restaurants that score 0 to 13 get their A right away. Others are re-inspected first, so their initial inspection row has no letter grade. That is why this case study uses the score.

Why did you leave out restaurant names?

This lesson compares boroughs, cuisines and violation types. Leaving out names and addresses keeps the practice file smaller and the focus on the method. The full dataset on NYC Open Data has them.

What does 'Critical' mean?

DOHMH flags as critical the violations most likely to contribute to food-borne illness, such as food held at the wrong temperature or evidence of mice.