Author: Ottavia M. Epifania
Date: 2026-08-20

# SC-IAT-example

#### Ottavia M. Epifania

#### 2026-08-20

    library(implicitMeasures)

This vignette illustrates how to use the `implicitMeasures` package for computing the SC-IAT D score. The illustration is based on the data set included in the package (i.e., `raw_data`).

### First thing first: Import and explore data

The labels that contains the specification `sc_` in the`blockcode` variable identify the SC-IAT blocks.

    data("raw_data")
    # explore the dataframe
    str(raw_data)
    #> 'data.frame':    84726 obs. of  6 variables:
    #>  $ Participant: int  4 4 4 4 4 4 4 4 4 4 ...
    #>  $ latency    : int  2592 628 808 783 2059 1114 608 663 771 676 ...
    #>  $ correct    : int  1 1 1 1 1 1 1 1 1 1 ...
    #>  $ trialcode  : Factor w/ 32 levels "age","alert",..: 31 5 3 20 3 20 5 3 20 3 ...
    #>  $ blockcode  : Factor w/ 13 levels "demo","practice.iat.Milkbad",..: 4 4 4 4 4 4 4 4 4 4 ...
    #>  $ response   : Factor w/ 46 levels "","0","1","19",..: 43 43 43 43 43 43 43 43 43 43 ...

    # explore the levels of the blockcode variable to identify the SC-IAT blocks
    levels(raw_data$blockcode)
    #>  [1] "demo"                      "practice.iat.Milkbad"
    #>  [3] "practice.iat.Milkgood"     "practice.sc_dark.Darkbad"
    #>  [5] "practice.sc_dark.Darkgood" "practice.sc_milk.Milkbad"
    #>  [7] "practice.sc_milk.Milkgood" "test.iat.Milkbad"
    #>  [9] "test.iat.Milkgood"         "test.sc_dark.Darkbad"
    #> [11] "test.sc_dark.Darkgood"     "test.sc_milk.Milkbad"
    #> [13] "test.sc_milk.Milkgood"

`raw_data` contains data from two different SC-IATs, one for the implicit assessment of the positive/negative evaluation of Milk chocolate (`sc_milk`), and one for the implicit assessment of the positive/negative evaluation of Dark chocolate (`sc_dark`).

Once the SC-IATs blocks have been identified, it is possible to clean the data for computing the D score. Function `clean_sciat` allows for cleaning the data set of either just one SC-IAT or to clean the data sets of two SC-IATs concurrently. The labels identifying the test blocks must be specified as a character vector via argument `block_sciat_1` and argument `block_sciat_2` (use the `block_sciat_2` argument only if there is a second SC-IAT). The labels identifying the demographic information (if any) must be passed to the `trial_demo` argument, after specifying the column of the data set containing the labels of the demographic information (argument `demo_id`).

DON’T USE THE `trial_eliminate` ARGUMENT TO ELIMINATE TRIALS EXCEEDING THE RESPONSE TIME WINDOW (rtw).

The labels for identifying the responses beyond the rtw (that have to be eliminated) must be included in the variable identified by the`trial_id` label, but they have to be specified via the `non_response` argument in the `compute_sciat()` function to actually be deleted.

    data("raw_data")
    sciat_data <- clean_sciat(raw_data, sbj_id = "Participant",
                             block_id = "blockcode",
                             latency_id = "latency",
                             accuracy_id = "correct",
                             block_sciat_1 = c("test.sc_dark.Darkbad",
                                               "test.sc_dark.Darkgood"),
                             block_sciat_2 = c("test.sc_milk.Milkbad",
                                               "test.sc_milk.Milkgood"),
                             trial_id  = "trialcode",
                             trial_eliminate = c("reminder",
                                                 "reminder1"),
                             demo_id = "blockcode",
                             trial_demo = "demo")

Since two SC-IATs and demographic data were specified, `clean_sciat()` results in a list of 3 elements:

    str(sciat_data) # structure of the resulting List
    #> List of 3
    #>  $ sciat1:Classes 'sciat_clean' and 'data.frame':    23328 obs. of  5 variables:
    #>   ..$ participant: int [1:23328] 4 4 4 4 4 4 4 4 4 4 ...
    #>   ..$ block      : chr [1:23328] "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" ...
    #>   ..$ trial      : Factor w/ 32 levels "age","alert",..: 5 3 5 3 20 3 5 20 5 5 ...
    #>   ..$ correct    : int [1:23328] 1 1 1 1 1 1 1 1 1 1 ...
    #>   ..$ latency    : int [1:23328] 461 1495 639 573 671 643 714 1190 625 517 ...
    #>  $ sciat2:Classes 'sciat_clean' and 'data.frame':    23328 obs. of  5 variables:
    #>   ..$ participant: int [1:23328] 4 4 4 4 4 4 4 4 4 4 ...
    #>   ..$ block      : chr [1:23328] "test.sc_milk.Milkbad" "test.sc_milk.Milkbad" "test.sc_milk.Milkbad" "test.sc_milk.Milkbad" ...
    #>   ..$ trial      : Factor w/ 32 levels "age","alert",..: 3 23 3 3 3 23 23 23 20 20 ...
    #>   ..$ correct    : int [1:23328] 1 1 1 1 1 1 1 1 1 1 ...
    #>   ..$ latency    : int [1:23328] 653 990 594 550 818 591 570 620 661 623 ...
    #>  $ demo  :'data.frame':  3726 obs. of  6 variables:
    #>   ..$ participant: int [1:3726] 4 4 4 4 4 4 4 4 4 4 ...
    #>   ..$ latency    : int [1:3726] 53047 53047 53047 53047 21554 21554 11266 11266 11266 11266 ...
    #>   ..$ correct    : int [1:3726] 1 1 1 1 1 1 1 1 1 1 ...
    #>   ..$ trialcode  : Factor w/ 32 levels "age","alert",..: 19 1 21 8 22 4 10 11 12 13 ...
    #>   ..$ blockcode  : Factor w/ 13 levels "demo","practice.iat.Milkbad",..: 1 1 1 1 1 1 1 1 1 1 ...
    #>   ..$ response   : Factor w/ 46 levels "","0","1","19",..: 33 15 41 34 16 20 1 1 1 1 ...
    #>  - attr(*, "class")= chr [1:2] "sciat_clean" "list"

The first two elements (`sciat1` and `sciat2`) are two `data.frame` with class `sciat_clean`. They contain the data of the SC-IATs specified in the `block_sciat1` and `block_sciat2` arguments of the `clean_sciat()` function, respectively. The third element (`demo`) is a `data.frame` that contains the demographic information as specified in the `trial_demo` argument of function `clean_sciat()`.

Each element of the resulting list can be stored in a separate object.

    sciat1 <- sciat_data[[1]] # extract first SC-IAT data
    sciat2 <- sciat_data[[2]] # extract second SC-IAT data
    demo_data <- sciat_data[[3]] # extract demographic information

    head(sciat1)
    #>    participant                block     trial correct latency
    #> 23           4 test.sc_dark.Darkbad  darkleft       1     461
    #> 24           4 test.sc_dark.Darkbad   badleft       1    1495
    #> 25           4 test.sc_dark.Darkbad  darkleft       1     639
    #> 26           4 test.sc_dark.Darkbad   badleft       1     573
    #> 27           4 test.sc_dark.Darkbad goodright       1     671
    #> 28           4 test.sc_dark.Darkbad   badleft       1     643
    head(demo_data)
    #>       participant latency correct trialcode blockcode response
    #> 81001           4   53047       1    gender      demo     male
    #> 81002           4   53047       1       age      demo       29
    #> 81003           4   53047       1       job      demo     stud
    #> 81004           4   53047       1       edu      demo       MD
    #> 81005           4   21554       1 milk_eval      demo        3
    #> 81006           4   21554       1 dark_eval      demo        4

### Compute the SC-IAT D score

Once the SC-IAT(s) data have been cleaned with the `clean_sciat()` function, it is possible to compute the D score by using function `compute_sciat()`.

This function takes three mandatory arguments and one optional argument. The three mandatory arguments are the data set with class `sciat_clean`, and the labels identifying the two critical associative conditions (arguments `mappingA` and `mappingB`). If the SC-IAT administration included a rtw, the label identifying the trials exceeding the threshold must be specified via the (optional) argument `non_response`.

    # Compute the D score for the first SC-IAT
     d_sciat1 <- compute_sciat(sciat1,
                      mappingA = "test.sc_dark.Darkbad",
                      mappingB = "test.sc_dark.Darkgood",
                      non_response = "alert")

    # dataframe containing the SC-IAT D score of the of the first SC-IAT
    str(d_sciat1)
    #> Classes 'dsciat' and 'data.frame':   162 obs. of  15 variables:
    #>  $ participant      : chr  "100" "101" "102" "103" ...
    #>  $ n_trial          : int  144 144 144 144 144 144 144 144 144 144 ...
    #>  $ no_response      : int  0 0 0 0 0 0 0 0 0 0 ...
    #>  $ nslow10000       : num  0 0 0 0 0 0 0 0 0 0 ...
    #>  $ nfast400         : num  0.03 0.05 0.01 0.01 0 0 0.01 0.11 0.02 0.05 ...
    #>  $ nfast350         : num  0.01 0.01 0 0 0 0 0 0.01 0 0 ...
    #>  $ out_accuracy     : chr  "keep" "keep" "keep" "keep" ...
    #>  $ accuracy.mappingA: num  0.986 0.986 0.958 0.986 1 ...
    #>  $ accuracy.mappingB: num  0.944 0.986 0.931 0.986 0.931 ...
    #>  $ RT_mean.mappingA : num  626 785 627 586 885 ...
    #>  $ RT_mean.mappingB : num  730 913 704 633 1056 ...
    #>  $ cond_ord         : chr  "MappingB_First" "MappingB_First" "MappingB_First" "MappingB_First" ...
    #>  $ legendMappingA   : chr  "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" "test.sc_dark.Darkbad" ...
    #>  $ legendMappingB   : chr  "test.sc_dark.Darkgood" "test.sc_dark.Darkgood" "test.sc_dark.Darkgood" "test.sc_dark.Darkgood" ...
    #>  $ d_sciat          : num  -0.413 -0.242 -0.393 -0.288 -0.314 ...

    # Compute D score for the second SC-IAT
     d_sciat2 <- compute_sciat(sciat2,
                      mappingA = "test.sc_milk.Milkbad",
                      mappingB = "test.sc_milk.Milkgood",
                      non_response = "alert")

     # dataframe containing the SC-IAT D score of the of the second SC-IAT
     head(d_sciat2)
    #>   participant n_trial no_response nslow10000 nfast400 nfast350 out_accuracy
    #> 1         100     144           0          0     0.02     0.01         keep
    #> 2         101     144           0          0     0.02     0.00         keep
    #> 3         102     144           0          0     0.02     0.00         keep
    #> 4         103     144           0          0     0.00     0.00         keep
    #> 5         104     144           0          0     0.00     0.00         keep
    #> 6         105     144           0          0     0.03     0.01         keep
    #>   accuracy.mappingA accuracy.mappingB RT_mean.mappingA RT_mean.mappingB
    #> 1         0.9436620         0.9722222         695.2269         648.8692
    #> 2         0.9861111         1.0000000         917.3706         699.7917
    #> 3         0.9583333         0.9166667         757.4988         784.3854
    #> 4         0.9861111         0.9722222         640.5077         607.7566
    #> 5         1.0000000         0.9861111         849.7500         928.0496
    #> 6         1.0000000         1.0000000         540.3099         614.8611
    #>         cond_ord       legendMappingA        legendMappingB     d_sciat
    #> 1 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood  0.16120777
    #> 2 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood  0.58453600
    #> 3 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood -0.08226841
    #> 4 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood  0.24119095
    #> 5 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood -0.26484892
    #> 6 MappingB_First test.sc_milk.Milkbad test.sc_milk.Milkgood -0.50147795

The `compute_sciat()` function results in a `data.frame` with class `dsciat` containing a number of rows equal to the number of participants, their D score, and a bunch of useful information on their performance (see the documentation for the `compute_sciat()` function for further information). The `descript_d()`, `d_point()`, and `d_density()` functions require the object resulting from the `compute_sciat()` function to work.

The computation of the SC-IAT D is such that positive scores indicate slower response times in the condition labeled as mapping A.

### Descriptive statistics

The summary method can be applied on the SC-IAT results as well.

    summary(d_sciat1) # Data frame containing SC-IAT D scores
    #> $general
    #>        measure value
    #> 1 Participants   162
    #> 2 Total trials 23324
    #>
    #> $statistics
    #>                   measure         mean           sd
    #> 1 Response time Mapping A 700.53321700 125.93988156
    #> 2 Response time Mapping B 710.22568799 125.28378587
    #> 3      Accuracy Mapping A   0.94935298   0.06674879
    #> 4      Accuracy Mapping B   0.94800255   0.06494543
    #> 5          SC-IAT D-score  -0.04118897   0.32127650
    #>
    #> attr(,"class")
    #> [1] "summary_dsciat" "list"

### Plotting the results

The `implicitMeasures` package comes with several functions for obtaining nice and clear representations of the results at both individual respondent and sample levels. Additionally, it includes functions for plotting SC-IAT D scores resulting from two different SC-IATs.

The plot method can be used as well on the SC-IAT results.

     plot(d_sciat1) # Data frame containing SC-IAT D scores