IAT-example

Ottavia M. Epifania

2019-08-02

library(implicitMeasures)

This vignette illustrates how to use implicitMeasures package to compute the IAT D-score by using the raw_data data set.

First thing first: Import and explore data

Labels containing the .iat specification in the blockcode variable identity the 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 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"

Once the IAT blocks have been identified, it is possible to prepare and clean the IAT data by means of the clean_iat() function. Since the data set also includes respondents’ demographic information (demo label in blockcode variable), it is possible to extract and store these information in a separate data frame:

iat_cleandata <- clean_iat(raw_data, sbj_id = "Participant",
                          block_id = "blockcode",
                          mapA_practice = "practice.iat.Milkbad",
                          mapA_test = "test.iat.Milkbad",
                          mapB_practice = "practice.iat.Milkgood",
                          mapB_test = "test.iat.Milkgood",
                          latency_id = "latency",
                          accuracy_id = "correct",
                          trial_id = "trialcode",
                          trial_eliminate = c("reminder", "reminder1"),
                          demo_id = "blockcode",
                          trial_demo = "demo")

Since the also the demographic data has been specified, clean_iat() results in a list of 3 elements:

str(iat_cleandata)
#> List of 3
#>  $ data_keep     :Classes 'iat_clean' and 'data.frame':  19440 obs. of  8 variables:
#>   ..$ participant   : int [1:19440] 4 4 4 4 4 4 4 4 4 4 ...
#>   ..$ latency       : int [1:19440] 1282 1299 1435 1089 967 648 967 615 729 642 ...
#>   ..$ correct       : int [1:19440] 1 1 1 1 1 1 1 1 1 1 ...
#>   ..$ block_original: chr [1:19440] "practice.iat.Milkbad" "practice.iat.Milkbad" "practice.iat.Milkbad" "practice.iat.Milkbad" ...
#>   ..$ condition     : chr [1:19440] "MappingA" "MappingA" "MappingA" "MappingA" ...
#>   ..$ block_pool    : chr [1:19440] "practice" "practice" "practice" "practice" ...
#>   ..$ block         : chr [1:19440] "practice_MappingA" "practice_MappingA" "practice_MappingA" "practice_MappingA" ...
#>   ..$ trial_id      : Factor w/ 32 levels "age","alert",..: 20 6 20 6 20 6 20 6 20 23 ...
#>  $ data_eliminate:'data.frame':  64638 obs. of  6 variables:
#>   ..$ Participant: int [1:64638] 4 4 4 4 4 4 4 4 4 4 ...
#>   ..$ latency    : int [1:64638] 2592 628 808 783 2059 1114 608 663 771 676 ...
#>   ..$ correct    : int [1:64638] 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 ...
#>  $ 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 ...

data_keep is a data.frame with class iat_clean. It contains the data to pass to the computeD() function.

data_eliminate is a data.framecontaining all the discarded blocks and trials, while demois a data.frame containing all the trials identified as demo in the blockcode variable.

Store the first data_keep in a data frame to pass to the computeD() function.

iat_data <- iat_cleandata[[1]]
head(iat_data)
#>   participant latency correct       block_original condition block_pool
#> 2           4    1282       1 practice.iat.Milkbad  MappingA   practice
#> 3           4    1299       1 practice.iat.Milkbad  MappingA   practice
#> 4           4    1435       1 practice.iat.Milkbad  MappingA   practice
#> 5           4    1089       1 practice.iat.Milkbad  MappingA   practice
#> 6           4     967       1 practice.iat.Milkbad  MappingA   practice
#> 7           4     648       1 practice.iat.Milkbad  MappingA   practice
#>               block  trial_id
#> 2 practice_MappingA goodright
#> 3 practice_MappingA darkright
#> 4 practice_MappingA goodright
#> 5 practice_MappingA darkright
#> 6 practice_MappingA goodright
#> 7 practice_MappingA darkright

Compute the D-score

Once the IAT have been prepared and cleaned through the clean_iat function, it is possible to compute the D-score by using the computeD() function.

This function only takes two elements: The first element is a data frame with class iat_clean, the second element is the D-score one wants to compute. For computing multiple D-score algorithms at the same time, use the multi_dgraph() function.

dscore <- computeD(iat_data, Dscore = "d3")
str(dscore)
#> Classes 'dscore' and 'data.frame':   162 obs. of  23 variables:
#>  $ participant               : int  4 6 8 11 14 17 18 19 20 21 ...
#>  $ n_trial                   : int  120 120 120 120 120 120 120 120 120 120 ...
#>  $ nslow10000                : num  0 0 0 0 0 0 0 0 0 0 ...
#>  $ nfast400                  : num  0 0 0 0.01 0.08 0.04 0 0.05 0 0 ...
#>  $ nfast300                  : num  0 0 0 0 0 0 0 0 0 0 ...
#>  $ accuracy.practice_MappingA: num  1 0.95 0.7 0.9 0.95 0.9 0.95 0.95 0.85 0.9 ...
#>  $ accuracy.practice_MappingB: num  1 1 0.85 0.95 1 1 1 0.85 1 0.85 ...
#>  $ accuracy.test_MappingA    : num  1 0.9 1 0.95 0.9 0.925 0.95 0.95 0.8 0.9 ...
#>  $ accuracy.test_MappingB    : num  1 1 0.85 0.95 1 0.95 1 0.975 0.975 0.9 ...
#>  $ accuracy.MappingA         : num  1 0.917 0.9 0.933 0.917 ...
#>  $ accuracy.MappingB         : num  1 1 0.85 0.95 1 ...
#>  $ RT_mean.MappingA          : num  1037 1179 954 1297 852 ...
#>  $ RT_mean.MappingB          : num  788 596 926 731 604 ...
#>  $ mean_practice_MappingA    : num  1070 1224 1504 1608 821 ...
#>  $ mean_test_MappingA        : num  1021 1157 679 1141 867 ...
#>  $ mean_practice_MappingB    : num  889 611 1108 702 637 ...
#>  $ mean_test_MappingB        : num  737 589 836 745 587 ...
#>  $ d_practice_d3             : num  -0.647 -1.274 -0.584 -1.114 -0.514 ...
#>  $ d_test_d3                 : num  -0.878 -1.226 0.508 -0.816 -0.672 ...
#>  $ dscore_d3                 : num  -0.762 -1.25 -0.038 -0.965 -0.593 ...
#>  $ cond_ord                  : chr  "MappingA_First" "MappingB_First" "MappingB_First" "MappingA_First" ...
#>  $ legendMappingA            : chr  "practice.iat.Milkbad_and_test.iat.Milkbad" "practice.iat.Milkbad_and_test.iat.Milkbad" "practice.iat.Milkbad_and_test.iat.Milkbad" "practice.iat.Milkbad_and_test.iat.Milkbad" ...
#>  $ legendMappingB            : chr  "practice.iat.Milkgood_and_test.iat.Milkgood" "practice.iat.Milkgood_and_test.iat.Milkgood" "practice.iat.Milkgood_and_test.iat.Milkgood" "practice.iat.Milkgood_and_test.iat.Milkgood" ...

The computeD() function results in a data.frame with class dscore containing a number of rows equal to the number of participants, their D-scores and a bunch of useful information on their performance (see the documentation of the computeD() function for further details on the resulting data frame). Functions IATrel(), dscr_d(), d_plot(), and d_distr() require the object resulting from the computeD function.

IAT descriptive statistics and reliability

The descriptive statistics of the D-score, computed on the practice and test blocks and the actual D-score, can be easily obtained by means of the dscr_d() function:

descript_d(dscore)
#>             Mean   SD   Min  Max
#> D-score    -0.56 0.54 -1.59 1.29
#> D-practice -0.59 0.64 -1.59 1.26
#> D-test     -0.54 0.56 -1.59 1.32

By specifying latex = TRUE, the dscr_d() print the results in Latex:

descript_d(dscore, latex = T)
#> % latex table generated in R 3.6.1 by xtable 1.8-4 package
#> % Fri Aug 02 13:46:05 2019
#> \begin{table}[ht]
#> \centering
#> \begin{tabular}{rrrrr}
#>   \hline
#>  & Mean & SD & Min & Max \\ 
#>   \hline
#> D-score & -0.56 & 0.54 & -1.59 & 1.29 \\ 
#>   D-practice & -0.59 & 0.64 & -1.59 & 1.26 \\ 
#>   D-test & -0.54 & 0.56 & -1.59 & 1.32 \\ 
#>    \hline
#> \end{tabular}
#> \end{table}

The IATrel() computes the IAT reliability as the correlation between the D-scores computed on the practice and test blocks across participants (see Gawronski et al. 2017 for further details):

IATrel(dscore)
#> $`Test-pratice Reliability`
#> [1] 0.65
#> 
#> $`Number of participants`
#> [1] 162
#> 
#> attr(,"class")
#> [1] "IATrel"

Plotting the results

implicitMeasures provides the users with different functions for plotting the results, either at the individual or at the sample level. Furthermore, it gives the chance to compute and plot multiple D-score algorithms at the same time.

Individual level

d_plot() plots the D-score for each participant in the sample. Participants can follow the order they had in the original data frame (default), or they can be ordered by increasing or decreasing D-score (D-increasing and D-decreasing, respectively). The values labels of the x-axis can be removed by setting x_values = FALSE (suggested in case of big sample size). The include_stats (default = FALSE) argument plots the descriptive statistics of the D (mean +/- 2sd).

d_plot(dscore)

# change respondents order, remove x-values
d_plot(dscore, order_sbj = "D-increasing", 
       x_values = FALSE)

# change respondents order, remove x-values, and add decsriptive statistics
d_plot(dscore, order_sbj = "D-decreasing", 
       x_values = FALSE, include_stats = TRUE)

Points color can be changed as well by setting col_point argument equal to the desired color (e.g., col_point = "lightskyblue").

Sample level

d_distr() plots the distribution of the D-scores. It provides different options for choosing the most appropriate distribution by means of the graph argument, that can be set equal to histogram (histogram plot, default), density (density plot), or violin (violin plot). Descriptive statistics can be added as well (include_stats = TRUE). The filling color for the histogram and the density plot can be modified by means of the col_fill argument (e.g., col_fill = "seagreen"). The col_point argument can be used to change the color of the points in the violin plot (e.g., col_fill = "royalblue").

d_distr(dscore)

# change the number of bins
d_distr(dscore, n_bin = 120)

# change graph and add descriptive statistics
d_distr(dscore, graph = "density", include_stats = TRUE)

# change graph and add descriptive statistics
d_distr(dscore, graph = "violin", include_stats = TRUE)

Multiple D-scores

multi_dscore() computes and plot multiple D-score algorithms. The multiple D-scores that can be computed depend on IAT administration. If it included a feedback strategy, only D1 and D2 should be computed (ds = "built-in"), otherwise D-score from D3 to D6 should be computed (ds = "error-inflation").

multi_scores <- multi_dscore(iat_data, ds = "error-inflation")

multi_dscore() results in a list containing two objects. The first object is a data.frame containing all the computed algorithms.

multi_d <- multi_scores[[1]]
head(multi_d)
#>   participant   dscore_d3   dscore_d4   dscore_d5   dscore_d6
#> 1           4 -0.76242699 -0.76242699 -0.76242699 -0.76242699
#> 2           6 -1.24976744 -1.26905702 -1.24976744 -1.26905702
#> 3           8 -0.03801459  0.02021915 -0.03801459  0.02021915
#> 4          11 -0.96488057 -0.97207623 -0.95538961 -0.96294963
#> 5          14 -0.59341709 -0.57385144 -0.59236921 -0.57213017
#> 6          17 -1.30474798 -1.27140694 -1.27997040 -1.26676628
str(multi_d)
#> 'data.frame':    162 obs. of  5 variables:
#>  $ participant: int  4 6 8 11 14 17 18 19 20 21 ...
#>  $ dscore_d3  : num  -0.762 -1.25 -0.038 -0.965 -0.593 ...
#>  $ dscore_d4  : num  -0.7624 -1.2691 0.0202 -0.9721 -0.5739 ...
#>  $ dscore_d5  : num  -0.762 -1.25 -0.038 -0.955 -0.592 ...
#>  $ dscore_d6  : num  -0.7624 -1.2691 0.0202 -0.9629 -0.5721 ...

The second object is a ggplot graph displaying the distribution of the algorithms.

multi_scores[[2]]

Gawronski, Bertram, Mike Morrison, Curtis E Phills, and Silvia Galdi. 2017. “Temporal Stability of Implicit and Explicit Measures: A Longitudinal Analysis.” Personality and Social Psychology Bulletin 43 (3): 300–312. https://doi.org/10.1177/0146167216684131.