Skip to main content
v2026.11,858 entries · CC-BY 4.0

Data Cleaning Steps for Research Data: A Practical Workflow

Data cleaning steps in order for research data: raw copy, text fixes, duplicates, missing values and a log, with OpenRefine, pandas and tidyr commands.

Written and maintained by CASRAI Editorial Board

Last updated

Data cleaning steps are best run in a fixed order, on a copy of the raw file, with every change written down. The order that works for most tabular research data is: keep the raw copy, inspect, fix whitespace and text, handle duplicates, handle missing values, then record what you did. This page gives that workflow with the exact commands and menu names from the current OpenRefine, pandas and tidyr documentation, and it shows the points where cleaning silently goes wrong.

For tool-by-tool reshaping and text-cleaning recipes, see data wrangling for research. This page is the ordered checklist that sits above those recipes.

What data cleaning is used for in research

Cleaning makes a dataset consistent enough that an analysis result depends on the data and not on typing accidents: stray spaces that split one category into two, the same record entered twice, or blanks that a program reads as zero. It is a step in the research data lifecycle, not a substitute for a quality framework; a data quality framework for research data describes the dimensions you check against. Cleaning decisions also belong in your reproducibility record, because each one changes what the final numbers mean.

Install or access (official sources only)

  • OpenRefine (no-code): download from openrefine.org/download. It is free software released under the BSD 3-clause license. The download page lists version 3.10.0, dated 2026-02-26, with Windows, Mac OS and Linux builds; the Windows ZIP includes an embedded Java install.
  • pandas (Python): installation instructions are on the official site, pandas.pydata.org. The commands below follow the current pandas reference documentation, where inplace is deprecated, so they assign results back to a variable instead.
  • tidyr (R): documented at tidyr.tidyverse.org; the drop_na reference page is for tidyr 1.3.2.

Step-by-step: the data cleaning workflow

  1. Keep the raw file untouched. Save the original as read-only and do all cleaning on a copy or in a script that reads the original. A script that goes raw file to clean file can be re-run; manual edits in a spreadsheet cannot be replayed.
  2. Inspect before changing anything. Count rows, list column types, and look at the values in each categorical column. Look at the distinct values in every categorical column, since spelling and spacing variants show up there first. For the structure itself (one variable per column, one observation per row), see tidy data rules.
  3. Fix whitespace and text variants.
    • OpenRefine: Edit cells > Common transforms > Trim leading and trailing whitespace, then Collapse consecutive whitespace.
    • OpenRefine: Edit cells > Cluster and edit groups values that probably mean the same thing. The key collision methods are Fingerprint, N-gram Fingerprint, Metaphone3, Cologne Phonetic, Daitch-Mokotoff and Beider-Morse; the nearest neighbor methods are Levenshtein Distance and PPM. Keying means assigning a group, or key, to a data value, and you choose which grouped values to merge.
  4. Find duplicates, inspect them, then drop them. In pandas the signature is DataFrame.duplicated(subset=None, keep='first'). By default all columns are used to identify a duplicate; pass subset to compare only an identifier column such as a participant ID. keep='first' marks every duplicate except the first occurrence, keep='last' marks all except the last, and keep=False marks every copy. The method returns a boolean Series. Use keep=False to look at every copy side by side before deciding which row to retain, then remove the unwanted ones.
  5. Decide what to do about missing values. First work out why values are missing; MCAR, MAR and MNAR explains why that decides whether deleting rows is safe. Then:
    • pandas DataFrame.dropna(*, axis=0, how=<no_default>, thresh=<no_default>, subset=None, inplace=<no_default>, ignore_index=False). df.dropna() drops rows containing any missing value, df.dropna(how="all") drops only rows that are entirely missing, df.dropna(thresh=2) keeps rows with at least two non-missing values (thresh cannot be combined with how), and df.dropna(subset=["name","toy"]) checks only the listed columns.
    • R tidyr: drop_na(data, ...) drops rows where any column named in ... contains a missing value; with no columns named, all columns are checked. df |> drop_na(x) checks only column x.
  6. Write the cleaning log. Record each step, the tool and command, the number of rows before and after, and the reason. A log with row counts lets a reviewer see that step 4 removed 12 rows and step 5 removed 40, without re-running anything. Document the final column meanings in a codebook.

Output and how to read it

After each step, compare row counts to the step before. A step that removes far more rows than expected usually means a subset or how setting was wrong, not that the data was that dirty. duplicated() returns True or False per row, so df.duplicated(subset=["id"], keep=False).sum() counts every row involved in a duplicate pair, while a plain keep='first' count only counts the surplus copies. The cleaning log from step 6 is the output you hand to collaborators along with the clean file.

Troubleshooting

Why does == np.nan find nothing?

Because the comparison is always False. The pandas missing-data guide states that equality comparisons between np.nan, NaT and NA do not act like None, and np.nan == np.nan is False. Use pd.isna() and pd.notna(); isna() also treats None as missing.

Why did an integer column turn into decimals?

pandas uses numpy.nan as the missing marker for NumPy dtypes, so an int64 column that gets a missing value is coerced to float64. Nullable types such as Int64, which use NA, avoid this coercion; convert_dtypes() converts a frame to them.

Why does inplace=True warn?

For dropna, inplace is deprecated since pandas 3.1.0 and will be removed in pandas 4.0. Assign the result instead: df = df.dropna(subset=["id"]).

Should I delete outliers as part of cleaning?

Not automatically. Flag unusual values, check them against the source record or instrument, and decide with the study protocol in hand; record the decision in the log either way.

Free alternatives

Tool Use it in this workflow for Documented feature
OpenRefine Step 3, text and whitespace Trim leading and trailing whitespace, Collapse consecutive whitespace, Cluster and edit
pandas Steps 4 and 5, duplicates and missing values duplicated(subset, keep), dropna(how, thresh, subset), isna(), convert_dtypes()
tidyr (R) Step 5, missing values drop_na()

FAQ

What are the main steps of data cleaning?

Keep a raw copy, inspect the data, standardise text and whitespace, deal with duplicates, deal with missing values, and log every change. The order matters because trimming whitespace first lets the duplicate check match records that differed only by a space.

Should I clean data before or after writing the data management plan?

Plan it first. A data management plan is where you say which versions of the data you will keep and how changes are documented, so the cleaning log has a place to live.

Is deleting rows with missing values acceptable?

Sometimes. It depends on why the values are missing and how many rows you lose; see the MCAR, MAR and MNAR guide linked above before using dropna() or drop_na() on a whole dataset.

Sources (official documentation, checked 2026-10-29)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Data Cleaning Steps for Research Data: A Practical Workflow

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.