An Automated Cleaning Tool for Semantic and Linguistic Data
Overview
Implements several functions that automates the cleaning and spell-checking of text data. Also converges, finalizes, removes plurals and continuous strings, and puts text data in binary format for semantic network analysis. Uses the 'SemNetDictionaries' package to make the cleaning process more accurate, efficient, and reproducible.
- UPDATE: package rebuilt from the ground up: one file per function, input checks up front, the fluency and free association code paths merged, and a
testthatsuite (there were no tests before) - ADD:
bad_response,best_guess,binary_to_responses,qwerty_distance,read_data, andresponses_to_binaryreplacebad.response,best.guess,bin2resp,qwerty.dist,read.data, andresp2bin; the dotted names still work - REMOVE:
lowercaseargument oftextcleaner; responses are always lowercased because capitalization does not change the word (a capital counted as a spelling error andCatcould be corrected tognat). Calls that passlowercasenow fail with "unused argument" - ADD:
keepRepeatsargument intextcleaner(fluency only) keeps repeated responses in$responses$clean(GitHub Issue #17);$responses$binaryand$behavioral$Perseverationsare unchanged - ADD:
$dictionary(the whole dictionary, reusable asdictionary = result$dictionary) and$added_words(only the words added in the session) in thetextcleaneroutput when the dictionary is saved "In my results" - ADD: the manual spell-check help opens in a separate browser window when the manual spell-check starts (and again with
H);options(SemNetCleaner.help_window = FALSE)keeps the help in the console - ADD: the instructions for reviewing the automated corrections (shown after the manual spell-check) open in a separate browser window too, followed by one ENTER prompt, instead of three screens of text in the console;
options(SemNetCleaner.help_window = FALSE)keeps the console instructions - UPDATE: requires
SemNetDictionaries(>= 0.3.0) (new category dictionaries and monikers, and a classed warning for a dictionary that cannot be found); a missing dictionary still stops with thetextcleanermessage when none loads, and gives one warning naming it when only some are missing - FIX: saving the dictionary at the end of the manual spell-check under a name that already exists kept the old file and lost the words added in that session
- FIX: a cell that holds only spaces in the review of the automated corrections is now treated as missing (a space typed to clear
to_2left a blank response in the cleaned data) - FIX: the review app for the automated corrections (
automated_edit) redrew the whole table after every edit, so the user lost their place; the table is now processed in the browser and an edit no longer redraws it - UPDATE: the review of the automated corrections shows only the responses the automated spell-check changed (
$spellcheck$automated, as documented); responses that were already correct are no longer listed, and the review is skipped when nothing changed (open.animals: 462 rows instead of 793)
Show all changes in 2.0.0Hide the rest of the changes in 2.0.0
- ADD:
options(SemNetCleaner.pause = FALSE)turns off the deliberate pauses in the console wizard - UPDATE:
parallel_process(used bytextcleaner) no longer changes the global random seed - ADD:
best_guessuses a phonetic (Metaphone) match alongside the QWERTY keyboard distance ("graple"is now corrected); when the two disagree the response goes to manual review - UPDATE:
keepStrings = TRUE(fluency) splits a string of dictionary words unless the whole string is a dictionary entry ("sea slug" stays, "marmoset otter" becomes "marmoset" and "otter", "sea slug dog" becomes "sea slug" and "dog"); withkeepStrings = FALSEa dictionary entry inside a longer string is kept whole - UPDATE: with
keepStrings = FALSE, a multi-word string that cannot be split automatically is asked about word by word, and strings are separated unless they are dictionary entries - UPDATE: BAD WORD with
keepStrings = TRUEdrops only the bad word and keeps the rest of the string (oneNAis kept for the intrusion count); BAD STRING still drops the whole string - UPDATE: ID columns are only inferred when they look like IDs (numeric, or every value contains a digit); the names
Participants,IDs,Subjects, etc. are recognized; explicit row names are used as IDs when there is no ID column (also forpartBY = "col") - UPDATE: task
typeis detected from the presence ofCueandResponsecolumns rather thanncol(data) > 3 - UPDATE: duplicated or missing participant IDs are an error naming the values and rows (they were silently renamed)
- UPDATE: unusable input (
NULL, no rows or columns, all responses missing, a failed preparation step) stops with a plain-language error instead of printing a bug report and returningNULL - UPDATE:
correct_changes(throughtextcleaner) opens the Shiny/DTreview app on every operating system (Linux usededit); passedit_fn = editfor no extra packages. A review table with extrato_columns is accepted - UPDATE: separators written without spaces (
cow/pig,fish,bird) separate words, digits inside words are kept for the spell-check, accented characters are transliterated ("cafe"), and runs of spaces are collapsed - UPDATE: words typed in the manual spell-check receive the same cleaning as every other response
- UPDATE: typing
xor pressing ENTER at "Please enter a new selection:" exits; GO BACK across responses is announced and documented - UPDATE: dependencies:
hunspellandphonicsare nowImports;pbapply,parallel, andeasycsvare dropped;shiny,DT,promises,tcltk, andrstudioapiareSuggestsonly, and so areforeign,readxl, andR.matlab, whichread_dataneeds only for.sav,.xls/.xlsx, and.matfiles (it names the package to install); requires R (>= 4.0.1) andSemNetDictionaries(>= 0.2.1) - UPDATE: parallel processing uses
future,future.apply, andprogressr; the worker plan is always restored. Workers load the installed package, socores > 1needs the package installed - REMOVE: the vignettes (and the
knitr,rmarkdown,markdown, andhtmlTablesuggestions); the tutorial is Christensen and Kenett (2021, https://doi.org/10.1037/met0000463) - UPDATE: faster spell-checking against very large dictionaries such as
"general"(370,000 words) - MOVE:
textcleaner_shiny(point-and-click wizard) and the functions that support it are internal while the app is developed - FIX:
correct_dataperseverations were always 0 for a participant with no"NA"response (3 instead of 116 inopen.animals); the same empty-which()negative index also emptied other vectors, matrix columns, and lists - FIX: a manual edit made while reviewing automated corrections was discarded for fluency data
- FIX:
textcleanercrashed with the defaultpartBY("the condition has length > 1") - FIX:
keepLengthfiltered nothing forkeepLength >= 2and everything forkeepLength <= 1 - FIX: GO BACK in the manual spell-check could discard every other recorded change; after a mistyped answer GO BACK and HELP replaced the word with
NA; withkeepStrings = TRUEand no suggestions GO BACK acted as BAD STRING - FIX: menus crashed on narrow consoles (
object 'def' not found) and printed1: SKIPtwice on consoles of 132 or more columns (GitHub Issues #20, #22, #26, #28) - FIX: data with one response column after the ID column failed (
attempt to set 'rownames' on an object with no dimensions) (GitHub Issue #16); data with three or fewer columns was treated as free association (GitHub Issue #18) - FIX: a single column of whole word lists stops with a message explaining the one-response-per-column format (GitHub Issue #25)
- FIX:
correct_dataoverflowed when a response was corrected into three or more words (GitHub Issue #23) - FIX: errors in the corrections review were hidden behind a dump of the results object (GitHub Issues #27, #29)
- FIX: a dictionary that cannot be found stops immediately, explaining that custom dictionaries are saved as
<name>.dictionary.rds;auto_spellcheckcrashed withkeepStrings = FALSEwhen no multi-word response could be corrected (GitHub Issues #21, #24) - FIX: saving a dictionary with "choose the directory" falls back to the working directory when
tcltkcannot load (GitHub Issue #24);add.path = "choose"is resolved once, up front - FIX: a dictionary name that is not a valid file name, or a failed save, no longer loses the manual session; names are validated and a failed save keeps the dictionary in
$dictionary - FIX: participant IDs came back space-padded when the ID column was numeric
- FIX: pressing ENTER at "TYPE MY OWN WORD" or "TYPE MY OWN STRING" crashed; menu answers with stray whitespace were rejected
- FIX: the HELP screen and the walkthrough described the wrong option numbers and wording under
keepStrings = TRUE - FIX:
allowNumbers = TRUEand capital letters crashed the automated spell-check (qwerty_distancenow lowercases and has digits on the keyboard);allowPunctuations = ""crashed - FIX: a single participant failed;
continue =a finished result failed withargument is of length zeroand now explains what can be continued - FIX: resuming after exiting at a single-word decision could fail with
input 'word' has length 0 - FIX: a response that repeats an unknown word ("teh cat teh dog") stopped the run; the word is now asked about once for all occurrences
- FIX: "pollar bear" became "polar bear bear", "tardigrade goose" lost "goose", "sea sponge" became "seal sponge", and "english cocker spaniel" repeated "spaniel"; "sting" in "sting ray" was asked about although "sting ray" is a dictionary entry
- FIX: free association: KEEP ORIGINAL and a one-word TYPE MY OWN STRING garbled the response; a response reduced to nothing (all stop words) aborted the final cleaning; the moniker lists returned capitalized proper nouns ("I do know")
- FIX:
convert2snafuwith a single dataset wrote an empty file - FIX:
qwerty_distanceandsingularizewere never exported;bad.responsewas defined twice and the unreviewed copy won at load time - FIX: several
1:length(),1:nrow(), and1:ncol()ranges ran backwards on empty or one-row input
From NEWS in the release
Install
Health
- OK13 OK2026-10-21
- NOTE11 OK, 2 NOTE2026-07-16
- OK14 OK2026-03-10
Documentation
- Help pages
- 26 (11 internal)includes a package overview page
- Examples that run
- 100%14 run in a plain check (2 of them under a condition)
- Exported functions with examples
- 100%
- Documented parameters
- 100%
- Return-value docs
- 100%
- Help pages citing references
- 27%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- 8
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Releases over time
Issues over time
PRs over time
Commits over time
3 development-tooling and community-health practices detected across 2 families in the upstream repository
Checks run against github.com/alexchristensen/semnetcleaner on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-09-12Commits: at least 1 crediting it in the message
- Claude Sonnet 51 commit · Sep 2026
Dependencies
Installing SemNetCleaner adds 15 packages (8 with compiled code, 27 MB of source tarballs). Heaviest: stringi 11 MB, data.table 5.7 MB, hunspell 3.1 MB.
Code & Tests
Datasets
People & History
Maintainer since 0.1.1 (2018)
Pick two releases to compare their code metrics.
- 2.0.0Latest2026-10-16 · current release · diff ↗ ··
added 6 exports
bad_response, best_guess, binary_to_responses, qwerty_distance, read_data, responses_to_binarylisted once in CRAN's queue
Seen in one reading of CRAN's incoming queue, at 2026-10-16 12:54 UTC, so it stayed less than the time between readings. - RR 4.6.0 released · 2026-04-24
- 1.3.7
- RR 4.5.0 released · 2025-04-11
- RR 4.4.0 released · 2024-04-24
- RR 4.3.0 released · 2023-04-21
- RR 4.2.0 released · 2022-04-22
- 1.3.42021-09-16 · diff ↗
- 1.3.32021-08-16 · diff ↗
- RR 4.1.0 released · 2021-05-18
- 1.3.1
- 1.3.0
- 1.2.02020-06-09 · diff ↗ ·
removed 16 exports
bad.response, combine.responses, converge, destr, dup.match, equate, finalize, full.match, is.letter, moniker, multi.word.check, rm.lead.space, spell.check.dictionary, splitstr.check, starting.letter, word.check.wrapperadded 1 export
resp2bin - RR 4.0.0 released · 2020-04-24
- 1.1.52020-03-22 · diff ↗
- 1.1.42020-02-17 · diff ↗
Show 9 earlier eventsHide 9 earlier events
- 1.1.32019-12-02 · diff ↗
- 1.1.22019-10-28 · diff ↗
- 1.1.12019-09-27 · diff ↗ ·
removed 4 exports
autoConverge, autoDestr, corr.chn, equate.multiadded 2 exports
correct.changes, read.data - 1.1.02019-08-06 · diff ↗ ·
removed 5 exports
add.let, chn.let, misnomer, miss.let, spell.optadded 2 exports
dup.match, moniker - 1.0.02019-07-01 · diff ↗ ·
removed 2 exports
normalize, spell.check.databaseadded 13 exports
bad.response, combine.responses, corr.chn, equate.multi, full.match, is.letter, multi.word.check, pluralize, qwerty.dist, rm.lead.space, spell.check.dictionary, starting.letter, word.check.wrapper - RR 3.6.0 released · 2019-04-26
- 0.9.92018-07-28 · diff ↗ ·
removed 9 exports
autoDeStr, convert2cytoscape, cosine, org.plot, partboot, partboot.plot, partboot.test, semnetcleaner, semnetmeasadded 13 exports
add.let, autoDestr, best.guess, bin2resp, chn.let, misnomer, miss.let, normalize, singularize, spell.check.database, spell.opt, splitstr.check, textcleaner - 0.1.12018-05-16
- RR 3.5.0 released · 2018-04-23
Package metadata
- First published
- 2018-05-16
- Total releases
- 16 / 8 yrs
- License
- GPL (>= 3.0)
- Minimum R
- ≥ 4.0.1
- Bundled data
- 134 KB / 4 files
- Download size
- 262 KB
Cite
Cite this package
Run in R for the authors' entry:
citation("SemNetCleaner")The package provides a citation file, so citation() returns the authors' own entry.
It points to 10.1037/met0000463.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-22, which the citation names so these numbers can be found later. More on citing and the projects behind them.