Changelog
SADCAT 2.0.0
Data corrections (breaking)
- Full consistency repair of the dictionary datasets (
All.steps_Dictionaries,All.steps_Dictionaries_FT,Spanishdicts,Sentiments):- Direction columns now contain only -1, 0, +1, or NA. Two corrupted “2” codings were repaired (“accepting” is +1 on Morality and Warmth; the censorial/censoring/censorship family is -1 on both), along with their corrupted SentiWordNet/AFINN valence cells.
- Membership and direction are now consistent everywhere: a word has a direction if and only if it is a member of that directional dimension. 97 Politics/Religion membership flags were added for manually added words that carried directions; roughly 150 member words with missing directions were manually coded; stray directions on non-member words were removed.
-
_dict_hi/_dict_locolumns rebuilt as membership plus direction (+1 / -1). About 1,400 word-dimension pairs from the manually added vocabulary now contribute to pipeline direction scoring, so direction scores will shift relative to earlier versions. -
Valrecomputed from its component columns;_dict_Pos/_dict_Negrecomputed as membership crossed with the sign ofVal. - 38 duplicated
All.steps_Dictionariesrows merged; value columns cleaned (stray strings, trailing spaces, TRUE/FALSE casing,values2/values3normalized to the documented recipe). - Dimension hierarchy enforced: Sociability or Morality membership implies Warmth membership; Ability or Assertiveness membership implies Competence membership.
- Removed legacy columns
Beliefs_dict_ABC*,work_dir_dummy, andbeliefsother_dir_dummyfrom all datasets. -
DictionariesandDictionaries_FTare no longer shipped as package data.Dictionarieswas stale relative toAll.steps_Dictionaries(it lacked about 1,100 stems, including all manually added vocabulary). Both files remain available unchanged inarchived-data/on GitHub. - Removed
Code_words()andCode_single(), the legacy word-coding API built on the archivedDictionariesdata. Use the current pipeline (preprocess_text(),score_valence(),match_dictionaries()) instead.Full_preprocess()now usesAll.steps_Dictionaries$values3as its spellcheck wordlist. - Documentation updated to the actual column set of
All.steps_Dictionaries(tv,values,values2,values3). - Please cite this data-corrected release as SADCAT 2.0.0.
SADCAT 0.2.0 (development)
New features
-
score_valence()adds three new dictionaries by default: SentiWordNet, Warriner et al. (2013) affective norms, and the Jockers/Rinker lexicon are now applied alongside the existing five (Lexicoder, NRC, Bing, AFINN, Loughran), bringing the combinedValenceYesNA/ValenceNoNAaverages to up to 8 dictionaries. New parameters:-
include_sentiwn(defaultTRUE),sentiwn_threshold(default0.10) use the SentiWordNet column already bundled inSentiments$Val_sentiwn, presence-based scoring at-1 / 0 / +1. The threshold filters marginal-magnitude entries (default 0.10 keeps about 32k of 38k). -
include_warriner(defaultTRUE) uses Warriner et al. (2013) norms bundled in the newWarriner_normsdataset (13,905 lemmas; original 1-9 Likert linearly rescaled to [-1, 1] via(V.Mean.Sum - 5) / 4). Continuous-valued: each text’sVal_warrineris the mean of matched-word valences. Validated on common English vocabulary; widely used in person-perception, social cognition, and prejudice research. -
include_jockers(defaultTRUE) uses the Jockers/Rinker lexicon bundled in the newJockers_normsdataset (11,697 entries; continuous valence in [-1, 1]). 13 entries from the upstreamlexiconsource fell outside [-1, 1] (e.g.,overly= -2,could have= -1.05,too much= -2) and were dropped because they are shifter / amplifier coefficients designed for sentimentr’s sliding-window aggregator, not independently sentiment-bearing words. Validation context is narrative/literary text rather than person perception specifically; use with that caveat.
Negation handling is preserved: a positive Warriner/Jockers word inside a negation scope contributes its negated value to the combined average. Set any
include_*toFALSEto opt out of an individual dictionary; set all three toFALSEto recover the prior 5-dictionary output exactly.Behavior change vs. 0.1.0: existing callers of
score_valence()will seeValenceYesNA/ValenceNoNAshift, additionalVal_*columns, and increased coverage of previously-no-match responses (≈22% rescue at default thresholds on a 47.8k-row human-response corpus). -
Data
- New bundled datasets
Warriner_normsandJockers_norms(seedata-raw/build_warriner_jockers.Rfor the build recipe; Warriner data is downloaded once from the journal’s supplementary materials and redistributed under Springer’s free supplementary terms; Jockers/Rinker is sourced from the MIT-licensedlexiconR package).
Bug fixes
singularize2()now actually singularizes -es plurals: a strayif (stringr::str_detect(word, "es$")) return(word)early-return made the irregular-plural switch (valves→valve,ladies→lady,boxes→box, etc.) and theves/ies/zes/ses/essuffix block dead code. Removed the early-return so those branches run as intended; also reordered the opening guards sois.na(word)is checked before dictionary membership. This is a behavior fix (correctness): words ending in-esthat were previously returned unchanged will now be singularized.singularize2()-zes/-sesbranch no longer over-strips: the branch previously stripped three trailing characters unconditionally, sofreezes→free,noses→no,roses→ro, etc. (results that happened to be valid dictionary entries with completely different meanings were silently accepted). It now tries candidate suffixes in order: strips(freezes→freeze,noses→nose,houses→house), then stripes(buses→bus,gases→gas,classes→class), then stripzes/ses(quizzes→quiz), keeping the first that’s inSemNetDictionaries::general.dictionary. Known remaining edge case: Latin-isplurals likecrisesstill mis-singularize becausegeneral.dictionarycontains spurious short fragments (e.g.,cris) that beatcrisis; fixing that requires dictionary cleanup, not logic changes.-
singularize2()no longer mangles short inputs and singular-ssnouns: three guards added.- Words shorter than 3 characters short-circuit and return unchanged (
"a"no longer becomes"on","i"no longer becomes"us","as"no longer becomes"a","is"no longer becomes"i"). - The final
-sstripping branch now skips words ending in-ss, preventingmass→masandpass→pas. - After any stripping rule, a candidate shorter than 3 characters falls back to the original word, preventing
bus→buandaxes→ax.
- Words shorter than 3 characters short-circuit and return unchanged (
Spellcheck2()no longer mangles NA markers: previously, hunspell would receive inputs like"n/a"and"?"and offer nonsense suggestions ("n/a"→"naan","?"→"s"), which then propagated through the pipeline and got aggregated as content responses instead of missing data.Spellcheck2()now short-circuits before hunspell when the input has no letters and no digits (pure punctuation:"?","--","...") or matches an explicit n/a variant ("n/a","N/A","n.a.","#N/A", etc.) and returns the canonical"na"placeholder.
Breaking changes
Global valence rename:
score_valence()now outputsValenceYesNAinstead ofValence.ValenceNoNAis unchanged. Downstream code that readsdata$Valencemust migrate todata$ValenceYesNA.-
Per-dimension valence columns renamed and extended:
match_dictionaries()now produces three per-dimension valence columns instead of two. The column formerly named{Dim}_valenceis now{Dim}_valenceStrictNA; the new default column is{Dim}_Valence(capital V):Old name New name Semantics {Dim}_valence{Dim}_valenceStrictNANA if dim not tagged or ValenceYesNAis NA(new) {Dim}_ValenceNA if dim not tagged; else ValenceNoNA(0 for sentiment-less tagged responses){Dim}_valenceNoNA{Dim}_valenceNoNAUnchanged: 0 if dim not tagged; NA only for missing response The most common substitution is
_valence→_Valence(capital V), which silently changes the semantics of downstream means: tagged responses with no matched sentiment words now contribute 0 (neutral) rather than being dropped as NA. Verify that this is the desired behaviour before migrating. match_dictionaries()default parameter:valence_coldefault changed from"Valence"to"ValenceYesNA"to match the renamed output ofscore_valence(). Callers that pass the old default explicitly must update.
Migration guide
# Old
data$Valence
combined$Sociability_valence
# New
data$ValenceYesNA # NA-gated global (was Valence)
data$ValenceNoNA # zero-imputed global (unchanged)
combined$Sociability_Valence # new default: NA when not tagged, else ValenceNoNA
combined$Sociability_valenceStrictNA # old "_valence" semantics
combined$Sociability_valenceNoNA # unchanged