Skip to contents

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_lo columns 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.
    • Val recomputed from its component columns; _dict_Pos / _dict_Neg recomputed as membership crossed with the sign of Val.
    • 38 duplicated All.steps_Dictionaries rows merged; value columns cleaned (stray strings, trailing spaces, TRUE/FALSE casing, values2/values3 normalized 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, and beliefsother_dir_dummy from all datasets.
  • Dictionaries and Dictionaries_FT are no longer shipped as package data. Dictionaries was stale relative to All.steps_Dictionaries (it lacked about 1,100 stems, including all manually added vocabulary). Both files remain available unchanged in archived-data/ on GitHub.
  • Removed Code_words() and Code_single(), the legacy word-coding API built on the archived Dictionaries data. Use the current pipeline (preprocess_text(), score_valence(), match_dictionaries()) instead. Full_preprocess() now uses All.steps_Dictionaries$values3 as 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 combined ValenceYesNA / ValenceNoNA averages to up to 8 dictionaries. New parameters:

    • include_sentiwn (default TRUE), sentiwn_threshold (default 0.10) use the SentiWordNet column already bundled in Sentiments$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 (default TRUE) uses Warriner et al. (2013) norms bundled in the new Warriner_norms dataset (13,905 lemmas; original 1-9 Likert linearly rescaled to [-1, 1] via (V.Mean.Sum - 5) / 4). Continuous-valued: each text’s Val_warriner is the mean of matched-word valences. Validated on common English vocabulary; widely used in person-perception, social cognition, and prejudice research.
    • include_jockers (default TRUE) uses the Jockers/Rinker lexicon bundled in the new Jockers_norms dataset (11,697 entries; continuous valence in [-1, 1]). 13 entries from the upstream lexicon source 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_* to FALSE to opt out of an individual dictionary; set all three to FALSE to recover the prior 5-dictionary output exactly.

    Behavior change vs. 0.1.0: existing callers of score_valence() will see ValenceYesNA / ValenceNoNA shift, additional Val_* 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_norms and Jockers_norms (see data-raw/build_warriner_jockers.R for 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-licensed lexicon R package).

Bug fixes

  • singularize2() now actually singularizes -es plurals: a stray if (stringr::str_detect(word, "es$")) return(word) early-return made the irregular-plural switch (valvesvalve, ladieslady, boxesbox, etc.) and the ves/ies/zes/ses/es suffix block dead code. Removed the early-return so those branches run as intended; also reordered the opening guards so is.na(word) is checked before dictionary membership. This is a behavior fix (correctness): words ending in -es that were previously returned unchanged will now be singularized.

  • singularize2() -zes / -ses branch no longer over-strips: the branch previously stripped three trailing characters unconditionally, so freezesfree, nosesno, rosesro, etc. (results that happened to be valid dictionary entries with completely different meanings were silently accepted). It now tries candidate suffixes in order: strip s (freezesfreeze, nosesnose, houseshouse), then strip es (busesbus, gasesgas, classesclass), then strip zes/ses (quizzesquiz), keeping the first that’s in SemNetDictionaries::general.dictionary. Known remaining edge case: Latin -is plurals like crises still mis-singularize because general.dictionary contains spurious short fragments (e.g., cris) that beat crisis; fixing that requires dictionary cleanup, not logic changes.

  • singularize2() no longer mangles short inputs and singular -ss nouns: three guards added.

    1. 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").
    2. The final -s stripping branch now skips words ending in -ss, preventing massmas and passpas.
    3. After any stripping rule, a candidate shorter than 3 characters falls back to the original word, preventing busbu and axesax.
  • 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 outputs ValenceYesNA instead of Valence. ValenceNoNA is unchanged. Downstream code that reads data$Valence must migrate to data$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}_valence is now {Dim}_valenceStrictNA; the new default column is {Dim}_Valence (capital V):

    Old name New name Semantics
    {Dim}_valence {Dim}_valenceStrictNA NA if dim not tagged or ValenceYesNA is NA
    (new) {Dim}_Valence NA if dim not tagged; else ValenceNoNA (0 for sentiment-less tagged responses)
    {Dim}_valenceNoNA {Dim}_valenceNoNA Unchanged: 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_col default changed from "Valence" to "ValenceYesNA" to match the renamed output of score_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