Configural Frequency Analysis Tutorial
Overview
This tutorial provides R code on conducting configural frequency analysis (Lienert & Krauth, 1975; Stemmler, 2020; von Eye, 1990). In brief, configural frequency analysis is similar to a chi-square test in that it uses a contingency table to determine whether instances are evenly distributed across categories. Beyond a chi-square test, however, configural frequency analysis identifies whether particular cells within a contingency table are over- or under-represented.
In this example, we use configural frequency analysis to examine the use of specific turn transitions during a subset (N = 59) of conversations between strangers in which one dyad member disclosed about a current problem. Each turn in the conversations between stranger dyads was coded (e.g., as an acknowledgement, question, hedged disclosure, etc.; see Bodie et al., 2021 in the Journal of Language and Social Psychology for more details about the creation of the turn typology) and the transitions between turn types was tallied across the entire sample. We use configural frequency analysis to determine which turn transitions occur more or less frequently than expected during these conversations.
We also add a third hypothetical variable to illustrate the value of configural frequency analysis for examining more than two variables at a time. Specifically, we add a hypothetical “condition” variable that represents an experimental manipulation in which dyads were assigned to communicate face-to-face or using computer-mediated communication. We include this hypothetical scenario following our initial demonstration of how configural frequency analysis was used in the Bodie et al. (2021) paper.
Note that the accompanying “ConfiguralFrequency_Tutorial_2023June16.rmd” file contains all of the code presented in this tutorial and can be opened in RStudio (a somewhat more friendly user interface to R).
Outline
In this tutorial, we’ll cover…
- Reading in the data and loading needed packages.
- Plotting two dyads’ conversation.
- Preparing the data for configural frequency analysis.
- Conducting configural frequency analysis.
- Adding a hypothetical experimental condition to the data.
- Conducting configural frequency analysis with three variables.
Read in the data and load needed libraries.
Let’s read the data into R.
The data set we are working with is called “StrangerConversations_N59” and is stored as a .csv file (comma-separated values file, which can be created by saving an Excel file as a csv document) on my computer’s desktop.
# Set working directory (i.e., where your data file is stored)
# This can be done by going to the top bar of RStudio and selecting
# "Session" --> "Set Working Directory" --> "Choose Directory" -->
# finding the location of your file
setwd("~/Desktop") # Note: You can skip this line if you have
#the data file and this .rmd file stored in the same directory
# Read in the data
<- read.csv(file = "StrangerConversations_N59.csv", head = TRUE, sep = ",")
data
# View the first 10 rows of the data
head(data, 10)
## id turn role turn_type
## 1 105 1 1 Question
## 2 105 2 2 Acknowledgement
## 3 105 3 1 Elaboration
## 4 105 4 2 Acknowledgement
## 5 105 5 1 Elaboration
## 6 105 6 2 Acknowledgement
## 7 105 7 1 Elaboration
## 8 105 8 2 Elaboration
## 9 105 9 1 Elaboration
## 10 105 10 2 Reflection
In the data, we can see each row contains information for one turn and there are multiple rows (i.e., turns) for each dyad. Specifically, there is a column for:
- Dyad ID (
id
)
- Time variable - in this case, turn in the conversation
(
turn
)
- Dyad member ID - in this case, role in the conversation
(
role
; discloser = 1, listener = 2)
- Turn type - in this case, based upon a typology derived in Bodie et
al. (2021;
turn_type
)
Load the R packages we need.
Packages in R are a collection of functions (and their documentation/explanations) that enable us to conduct particular tasks, such as plotting or fitting a statistical model.
# install.packages(data.table) # Install package if you have never used it before
library(data.table) # For data management: counting turn transitions
# install.packages("devtools") # Install package if you have never used it before
require(devtools) # For version control
#install.packages("confreq") # Install package if you have never used it before
library(confreq) # For conducting configural frequency analysis
# install.packages("dplyr") # Install package if you have never used it before
library(dplyr) # For data management
# install.packages("ggplot2") # Install package if you have never used it before
library(ggplot2) # For plotting
# install.packages("tidyverse")
library(tidyverse) # For data management
Plot Two Dyads’ Conversation.
To get a better feel for the conversation data, let’s plot two dyads’ conversations.
Before creating the plots, it is helpful to set the colors for each turn type so the color of the turn categories are consistent across plots (i.e., the number of turn types present in a given conversation does not affect the color of the turn types). We do this by creating a vector “cols” that contains color assignments (via hex code: https://www.color-hex.com/) for each turn type.
A note on accessibility: To make your plots accessible, you may consider adopting a colorblind-friendly palette. David Nichols’ website (https://davidmathlogic.com/colorblind/) provides a great explainer on this issue, as well as a color picking tool.
<- c("Elaboration" = "#00BA38",
cols "Question" = "#619CFF",
"Acknowledgement" = "#F8766D",
"Reflection" = "#DB72FB",
"Advice" = "#93AA00",
"HedgedDisclosure" = "#00C19F")
We’ll create the dyadic categorical time series plot for each exemplar dyad and save these plots to the objects “dyad105_plot” and “dyad123_plot”.
Dyad 105 plot.
# First partition data of interest
<- data[data$id == 105, ]
dyad105
<-
dyad105_plot # Choose the data, set time variable (turn) for the x-axis
ggplot(dyad105, aes(x = turn)) +
# Create title for plot by combining "Dyad = " with the dyad id variable (id)
ggtitle(paste("Dyad =", unique(dyad105$id))) +
# Create bars for the form of the listeners' turns
# Partition data for listeners (role = 2)
geom_rect(data = dyad105[dyad105$role == 2, ],
# Set the width of each bar as -0.5 and +0.5 the value of the time variable (turn)
mapping = aes(xmin = turn-.5, xmax = turn+.5,
# Set the height of each bar to range from 0 to 5
ymin = 0, ymax = 5,
# Set the color of each bar to correspond to each turn type
fill = turn_type)) +
# Add a horizontal line to separate bars
geom_hline(yintercept = 5, color = "black") +
# Create bars for the form of the disclosers' turns
# Partition data for disclosers (role = 1)
geom_rect(data = dyad105[dyad105$role == 1, ],
# Set the width of each bar as -0.5 and +0.5 the value of the time variable (turn)
mapping = aes(xmin = turn-.5, xmax = turn+.5,
# Set the height of each bar to range from 5 to 10
ymin = 5, ymax = 10,
# Set the color of each bar to correspond to each turn type
fill = turn_type)) +
# Set color of turn types to vector we created earlier ("cols")
scale_fill_manual(values = cols) +
# Label for x-axis
xlab("Turn") +
# Label for y-axis
ylab("Role") +
# X-axis ticks and labels
scale_x_continuous(breaks = seq(0, 110, by = 10)) +
# Y-axis ticks and label
scale_y_continuous(breaks = c(2.5, 7.5),
labels=c("Listener Turn", "Discloser Turn")) +
# Legend label
labs(fill = "Turn Type") +
# Additional plot aesthetics
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text=element_text(color = "black"))
Dyad 123 plot.
# First partition data of interest
<- data[data$id == 123, ]
dyad123
<-
dyad123_plot # Choose the data, set time variable (turn) for the x-axis
ggplot(dyad123, aes(x = turn)) +
# Create title for plot by combining "Dyad = " with the dyad id variable (id)
ggtitle(paste("Dyad =", unique(dyad123$id))) +
# Create bars for the form of the listeners' turns
# Partition data for listeners (role = 2)
geom_rect(data = dyad123[dyad123$role == 2, ],
# Set the width of each bar as -0.5 and +0.5 the value of the time variable (turn)
mapping = aes(xmin = turn-.5, xmax = turn+.5,
# Set the height of each bar to range from 0 to 5
ymin = 0, ymax = 5,
# Set the color of each bar to correspond to each turn type
fill = turn_type)) +
# Add a horizontal line to separate bars
geom_hline(yintercept = 5, color = "black") +
# Create bars for the form of the disclosers' turns
# Partition data for disclosers (role = 1)
geom_rect(data = dyad123[dyad123$role == 1, ],
# Set the width of each bar as -0.5 and +0.5 the value of the time variable (turn)
mapping = aes(xmin = turn-.5, xmax = turn+.5,
# Set the height of each bar to range from 5 to 10
ymin = 5, ymax = 10,
# Set the color of each bar to correspond to each turn type
fill = turn_type)) +
# Set color of turn types to vector we created earlier ("cols")
scale_fill_manual(values = cols) +
# Label for x-axis
xlab("Turn") +
# Label for y-axis
ylab("Role") +
# X-axis ticks and labels
scale_x_continuous(breaks = seq(0, 110, by = 10)) +
# Y-axis ticks and label
scale_y_continuous(breaks = c(2.5, 7.5),
labels=c("Listener Turn", "Discloser Turn")) +
# Legend label
labs(fill = "Turn Type") +
# Additional plot aesthetics
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text=element_text(color = "black"))
Print the plots we just created.
print(dyad105_plot)
print(dyad123_plot)
On the x-axis, we have turn in the conversation. On the y-axis, we have the turn type for the disclosers on the top half and the listeners on the bottom half. Each turn category is represented by a different color and the gray bars indicate when a particular dyad member is not speaking. We can see that Dyad 105 had greater back-and-forth exchange during their conversation, as indicated by the greater number of turns. In both dyads, we can see that the disclosers spent many of their turns elaborating on their problem (green) and the listener used a variety of different turn types.
Prepare the Data for Configural Frequency Analysis.
To prepare the conversation data for configural frequency analysis, we must first count the number of transitions between listener –> discloser turns and the number of transitions between discloser –> listener turns.
First, let’s make sure all the data are ordered by turn within each dyad.
# Order data by ID and turn number
<- data[order(data$id, data$turn), ]
data
# View the first 10 rows of the data
head(data, 10)
## id turn role turn_type
## 3805 3 1 1 Elaboration
## 3806 3 2 2 Acknowledgement
## 3807 3 3 1 HedgedDisclosure
## 3808 3 4 2 Acknowledgement
## 3809 3 5 1 HedgedDisclosure
## 3810 3 6 2 Acknowledgement
## 3811 3 7 1 Elaboration
## 3812 3 8 2 Question
## 3813 3 9 1 Elaboration
## 3814 3 10 2 Acknowledgement
Second, before calculating the number of turn transitions, we first need to distinguish between listener and discloser turns of the same label (e.g., listener question vs. discloser question) since these are not distinguished in the “turn_type” variable.
<- # Select data
data %>%
data # Update "turn_type" variable so that
# if the role = 1 (i.e., if it is a discloser turn),
# then add a "D" in front of turn type,
# otherwise add a "L" in front of turn type
# separate the D (or L) and the turn type with a "_"
::mutate(turn_type = paste0(ifelse(role == 1, "D", "L"), "_", turn_type)) %>%
dplyr# Save the data as a data.frame
as.data.frame()
# View the first 10 rows of the data
head(data, 10)
## id turn role turn_type
## 3805 3 1 1 D_Elaboration
## 3806 3 2 2 L_Acknowledgement
## 3807 3 3 1 D_HedgedDisclosure
## 3808 3 4 2 L_Acknowledgement
## 3809 3 5 1 D_HedgedDisclosure
## 3810 3 6 2 L_Acknowledgement
## 3811 3 7 1 D_Elaboration
## 3812 3 8 2 L_Question
## 3813 3 9 1 D_Elaboration
## 3814 3 10 2 L_Acknowledgement
Third, let’s create a lagged “turn_type” variable. This lagged variable will then be combined with the original “turn_type” variable to create a new variable that represents the turn transition.
After running the code, you will see below that the discloser’s first turn is shown as D_Elaboration. On the same line and in the next column, the first lagged turn is represented as NA to represent the fact that the listener did not speak prior to the discloser’s first turn.
# Create a lagged variable
<- # Select data
data %>%
data # Select grouping variable, in this case, dyad ID (id)
::group_by(id) %>%
dplyr# Create new variable that is a lag of "turn_type"
::mutate(lagged_turn_type = lag(turn_type)) %>%
dplyr# Save the data as a data.frame
as.data.frame()
# View the first 10 rows of the data
head(data, 10)
## id turn role turn_type lagged_turn_type
## 1 3 1 1 D_Elaboration <NA>
## 2 3 2 2 L_Acknowledgement D_Elaboration
## 3 3 3 1 D_HedgedDisclosure L_Acknowledgement
## 4 3 4 2 L_Acknowledgement D_HedgedDisclosure
## 5 3 5 1 D_HedgedDisclosure L_Acknowledgement
## 6 3 6 2 L_Acknowledgement D_HedgedDisclosure
## 7 3 7 1 D_Elaboration L_Acknowledgement
## 8 3 8 2 L_Question D_Elaboration
## 9 3 9 1 D_Elaboration L_Question
## 10 3 10 2 L_Acknowledgement D_Elaboration
We next generate a data frame containing transition frequencies through cross-tabulation, and save it to the data frame “data_dt”. Because there are 7 turn types (6 identified and 1 NA) and 2 roles (listener and discloser), there are 14 turn categories in our dataset. Thus, the crosstab table contains 14 * 14 = 196 cells, representing all pairings or combinations of two turns.
# Reformat data frame to data table
<- data.table::as.data.table(data)
data_dt
# Count the occurrence of lagged turn and turn pairs
<- as.data.frame(with(data_dt, table(turn_type, lagged_turn_type)))
data_counts
# Count the rows in data_counts
nrow(data_counts)
## [1] 196
Of course, not all of the 196 are legitimate turn transitions. Transitions that were at the beginning or end of the conversation and those that involved uncodable turns will need to be removed. In addition, while they exist in the table, D->D and L->L transitions do not occur in our data. We will remove them in the two code chunks below.
# Remove rows in which the lagged turn in the transition contains a _NA
<- data_counts[ grep("_NA", data_counts$lagged_turn_type, invert = TRUE) , ]
data_counts
# Remove rows in which the following turn in the transition contains a _NA
<- data_counts[ grep("_NA", data_counts$turn_type, invert = TRUE) , ]
data_counts
# Count the rows in data_counts
nrow(data_counts)
## [1] 144
Since we will be examining listener –> discloser and discloser –> listener turn transitions separately, we will create two different data sets that contain the counts of these turn transitions. We will also remove the L->L and D->D transitions at this step.
# Create listener --> discloser transition data set
# Remove all transitions that begin with a discloser turn from data_counts
# by selecting all rows in lagged_turn_type with the discloser tag "D_"
<- data_counts[ grep("D_", data_counts$lagged_turn_type, invert = TRUE) , ]
list2disc
# Remove all transitions that end with a listener turn to create the L->D subset
# by selecting all rows in turn_type with the listener tag "L_"
<- list2disc[ grep("L_", list2disc$turn_type, invert = TRUE) , ]
list2disc nrow(list2disc)
## [1] 36
# View the first 10 rows of the data
head(list2disc, 10)
## turn_type lagged_turn_type Freq
## 99 D_Acknowledgement L_Acknowledgement 28
## 100 D_Advice L_Acknowledgement 8
## 101 D_Elaboration L_Acknowledgement 767
## 102 D_HedgedDisclosure L_Acknowledgement 156
## 104 D_Question L_Acknowledgement 28
## 105 D_Reflection L_Acknowledgement 3
## 113 D_Acknowledgement L_Advice 10
## 114 D_Advice L_Advice 1
## 115 D_Elaboration L_Advice 31
## 116 D_HedgedDisclosure L_Advice 5
# Create discloser --> listener transition data set
# Remove all transitions that begin with a listener turn from data_counts
# by selecting all rows in lagged_turn_type with the listener tag "L_"
<- data_counts[ grep("L_", data_counts$lagged_turn_type, invert = TRUE) , ]
disc2list
# Remove all transitions that end with a discloser turn to create the D->L subset
# by selecting all rows in turn_type with the discloser tag "D_"
<- disc2list[ grep("D_", disc2list$turn_type, invert = TRUE) , ]
disc2list nrow(disc2list)
## [1] 36
# View the first 10 rows of the data
head(disc2list, 10)
## turn_type lagged_turn_type Freq
## 8 L_Acknowledgement D_Acknowledgement 16
## 9 L_Advice D_Acknowledgement 8
## 10 L_Elaboration D_Acknowledgement 119
## 11 L_HedgedDisclosure D_Acknowledgement 33
## 13 L_Question D_Acknowledgement 24
## 14 L_Reflection D_Acknowledgement 46
## 22 L_Acknowledgement D_Advice 11
## 23 L_Advice D_Advice 0
## 24 L_Elaboration D_Advice 5
## 25 L_HedgedDisclosure D_Advice 0
Given that we are examining the transitions between six listener turn types and six discloser turn types, we should expect each of our data sets to contain 36 rows. These rows represent all possible transitions, including a few transitions that were not observed in our dataset.
Finally, the confreq
package requires the data to be
organized in a specific way to conduct configural frequency analysis.
Specifically, each data set should have three columns that represent (1)
the type of lagged turn, (2) the current type of turn, and (3) the
frequency of that turn transition. In the first two columns, each turn
type needs to be represented by a number instead of a category label.
So, we number the categories in alphabetical order (1 = acknowledgement,
2 = advice, 3 = elaboration, 4 = hedged disclosure, 5 = question, 6 =
reflection). The code chunk below recodes the turn labels into
numbers.
# Recoding variables in listener --> discloser transition data set
<- # Select data
list2disc %>%
list2disc # Recode lagged turn and following turn variables with numbers
::mutate(lagged_turn_type = recode(list2disc$lagged_turn_type,
dplyr"L_Acknowledgement" = 1,
"L_Advice" = 2,
"L_Elaboration" = 3,
"L_HedgedDisclosure" = 4,
"L_Question" = 5,
"L_Reflection" = 6),
turn_type = recode(list2disc$turn_type,
"D_Acknowledgement" = 1,
"D_Advice" = 2,
"D_Elaboration" = 3,
"D_HedgedDisclosure" = 4,
"D_Question" = 5,
"D_Reflection" = 6)) %>%
# Save the data as a data.frame
as.data.frame()
# Recoding variables in discloser --> listener transition data set
<- # Select data
disc2list %>%
disc2list # Recode lagged turn and following turn variables with numbers
::mutate(lagged_turn_type = recode(disc2list$lagged_turn_type,
dplyr"D_Acknowledgement" = 1,
"D_Advice" = 2,
"D_Elaboration" = 3,
"D_HedgedDisclosure" = 4,
"D_Question" = 5,
"D_Reflection" = 6),
turn_type = recode(disc2list$turn_type,
"L_Acknowledgement" = 1,
"L_Advice" = 2,
"L_Elaboration" = 3,
"L_HedgedDisclosure" = 4,
"L_Question" = 5,
"L_Reflection" = 6)) %>%
# Save the data as a data.frame
as.data.frame()
Let’s reorder the values of the turn variables since they represent the turn categories in alphabetical order, and reorganize the columns so the lagged turns come first.
# Order data by lagged_turn_type and turn_type for listener --> discloser turn transitions
<- list2disc[order(list2disc$lagged_turn_type, list2disc$turn_type), ]
list2disc
# Reorder the columns for listener --> discloser turn transitions
<- list2disc[, c(2, 1, 3)]
list2disc
# View the first 10 rows of the data
head(list2disc, 10)
## lagged_turn_type turn_type Freq
## 99 1 1 28
## 100 1 2 8
## 101 1 3 767
## 102 1 4 156
## 104 1 5 28
## 105 1 6 3
## 113 2 1 10
## 114 2 2 1
## 115 2 3 31
## 116 2 4 5
# Order data by lagged_turn_type and turn_type for discloser --> listener turn transitions
<- disc2list[order(disc2list$lagged_turn_type, disc2list$turn_type), ]
disc2list
# Reorder the columns for discloser --> listener turn transitions
<- disc2list[, c(2, 1, 3)]
disc2list
# View the first 10 rows of the data
head(disc2list, 10)
## lagged_turn_type turn_type Freq
## 8 1 1 16
## 9 1 2 8
## 10 1 3 119
## 11 1 4 33
## 13 1 5 24
## 14 1 6 46
## 22 2 1 11
## 23 2 2 0
## 24 2 3 5
## 25 2 4 0
We can also rename the columns to represent the speaker of that turn.
# Rename columns in listener --> discloser turn transition data
colnames(list2disc) <- c("listener", "discloser", "freq")
# Rename columns in discloser --> listener turn transition data
colnames(disc2list) <- c("discloser", "listener", "freq")
Conduct the Configural Frequency Analysis.
Let’s examine the structure of the data sets.
We need to check whether the variables are in the correct format. Specifically, we need the variables that label the turn types of the listeners and disclosers to be factor variables (instead of integer variables). A factor variable makes sure R interprets the variables as categories instead of integers.
# Examine the structure of the listener --> discloser
# and discloser --> listener data
str(list2disc)
## 'data.frame': 36 obs. of 3 variables:
## $ listener : num 1 1 1 1 1 1 2 2 2 2 ...
## $ discloser: num 1 2 3 4 5 6 1 2 3 4 ...
## $ freq : int 28 8 767 156 28 3 10 1 31 5 ...
str(disc2list)
## 'data.frame': 36 obs. of 3 variables:
## $ discloser: num 1 1 1 1 1 1 2 2 2 2 ...
## $ listener : num 1 2 3 4 5 6 1 2 3 4 ...
## $ freq : int 16 8 119 33 24 46 11 0 5 0 ...
# Need the discloser and listener variables to be factors in both datasets
$listener <- as.factor(list2disc$listener)
list2disc$discloser <- as.factor(list2disc$discloser)
list2disc
$listener <- as.factor(disc2list$listener)
disc2list$discloser <- as.factor(disc2list$discloser) disc2list
Now that the data are in the correct format, we can run the configural frequency analyses.
Let’s first examine the listener to discloser transitions.
The configural frequency analysis function requires that the data are formatted as a response pattern frequency table.
# Change format of data for configural frequency analysis
# Insert data ("list2disc") in the dat2fre(fre2dat()) function
<- dat2fre(fre2dat(list2disc)) cfa_list2disc
## Number of categories for each variable
## estimated from data are:
## listener discloser
## 6 6
## --> 36 different configurations
# Examine the response pattern frequency table
cfa_list2disc
## listener discloser Freq
## 1 1 1 28
## 2 1 2 8
## 3 1 3 767
## 4 1 4 156
## 5 1 5 28
## 6 1 6 3
## 7 2 1 10
## 8 2 2 1
## 9 2 3 31
## 10 2 4 5
## 11 2 5 1
## 12 2 6 1
## 13 3 1 98
## 14 3 2 5
## 15 3 3 339
## 16 3 4 42
## 17 3 5 59
## 18 3 6 18
## 19 4 1 43
## 20 4 2 1
## 21 4 3 78
## 22 4 4 17
## 23 4 5 7
## 24 4 6 4
## 25 5 1 14
## 26 5 2 1
## 27 5 3 231
## 28 5 4 23
## 29 5 5 5
## 30 5 6 0
## 31 6 1 52
## 32 6 2 0
## 33 6 3 343
## 34 6 4 44
## 35 6 5 10
## 36 6 6 5
Next, we conduct the configural frequency analysis and save the results. We then examine a summary of the results.
# Conduct configural frequency analysis and save the results
# Insert the response pattern frequency table
# and the name of the variables of interest (with a ~ and +)
<- CFA(cfa_list2disc, form = "~ listener + discloser")
results_list2disc
# Examine the saved results
summary(results_list2disc , showall = TRUE)
## function Call:
## -------------
## Formula: ~ listener + discloser
## Variables: listener discloser
## Categories: 6 6
##
## results of global tests:
## -----------------------
## pearson Chi-square test:
## Chi df pChi alpha
## 1 304.3275 25 0 0.05
##
## likelihood ratio test:
## Chi df pChi alpha
## 1 294.2896 25 0 0.05
##
## Information Criteria:
## loglik AIC BIC
## 1 -227.0889 476.1777 493.5964
##
## results of local tests:
## -----------------------
## Type (+) / Antitype (-) based on: z.pChi ;
## with Bonferroni adjusted alpha: 0.001388889
## pat. obs. exp. Type df z.Chi z.pChi
## 1 1 1 28 97.881 - 1 -7.063 0.000
## 2 1 2 8 6.392 . 1 0.636 0.262
## 3 1 3 767 714.734 . 1 1.955 0.025
## 4 1 4 156 114.661 + 1 3.861 0.000
## 5 1 5 28 43.947 . 1 -2.406 0.008
## 6 1 6 3 12.385 . 1 -2.667 0.004
## 7 2 1 10 4.845 . 1 2.342 0.010
## 8 2 2 1 0.316 . 1 1.215 0.112
## 9 2 3 31 35.376 . 1 -0.736 0.231
## 10 2 4 5 5.675 . 1 -0.283 0.388
## 11 2 5 1 2.175 . 1 -0.797 0.213
## 12 2 6 1 0.613 . 1 0.494 0.311
## 13 3 1 98 55.466 + 1 5.711 0.000
## 14 3 2 5 3.622 . 1 0.724 0.235
## 15 3 3 339 405.016 - 1 -3.280 0.001
## 16 3 4 42 64.975 . 1 -2.850 0.002
## 17 3 5 59 24.903 + 1 6.833 0.000
## 18 3 6 18 7.018 + 1 4.145 0.000
## 19 4 1 43 14.831 + 1 7.315 0.000
## 20 4 2 1 0.969 . 1 0.032 0.487
## 21 4 3 78 108.293 . 1 -2.911 0.002
## 22 4 4 17 17.373 . 1 -0.089 0.464
## 23 4 5 7 6.659 . 1 0.132 0.447
## 24 4 6 4 1.877 . 1 1.550 0.061
## 25 5 1 14 27.090 . 1 -2.515 0.006
## 26 5 2 1 1.769 . 1 -0.578 0.282
## 27 5 3 231 197.815 . 1 2.359 0.009
## 28 5 4 23 31.734 . 1 -1.550 0.061
## 29 5 5 5 12.163 . 1 -2.054 0.020
## 30 5 6 0 3.428 . 1 -1.851 0.032
## 31 6 1 52 44.887 . 1 1.062 0.144
## 32 6 2 0 2.931 . 1 -1.712 0.043
## 33 6 3 343 327.767 . 1 0.841 0.200
## 34 6 4 44 52.582 . 1 -1.183 0.118
## 35 6 5 10 20.153 . 1 -2.262 0.012
## 36 6 6 5 5.680 . 1 -0.285 0.388
In the results, we can examine the column “Type” to determine which transitions occurred more (+) or less (-) frequently than expected. We can see that the transitions between (1) listener acknowledgements and discloser hedged disclosures, (2) listener elaborations and discloser acknowledgements, (3) listener elaborations and discloser questions, (4) listener elaborations and discloser reflections, and (5) listener hedged disclosures and discloser acknowledgements occurred more frequently than expected. Furthermore, transitions between (1) listener acknowledgements and discloser acknowledgements and (2) listener elaborations and discloser elaborations occurred less frequently than expected.
We next examine the discloser to listener transitions.
The configural frequency analysis function requires that the data are formatted as a response pattern frequency table.
# Change format of data for configural frequency analysis
# Insert data (disc2list) in the dat2fre(fre2dat()) function
<- dat2fre(fre2dat(disc2list)) cfa_disc2list
## Number of categories for each variable
## estimated from data are:
## discloser listener
## 6 6
## --> 36 different configurations
# Examine the response pattern frequency table
cfa_disc2list
## discloser listener Freq
## 1 1 1 16
## 2 1 2 8
## 3 1 3 119
## 4 1 4 33
## 5 1 5 24
## 6 1 6 46
## 7 2 1 11
## 8 2 2 0
## 9 2 3 5
## 10 2 4 0
## 11 2 5 2
## 12 2 6 0
## 13 3 1 790
## 14 3 2 33
## 15 3 3 329
## 16 3 4 94
## 17 3 5 195
## 18 3 6 361
## 19 4 1 160
## 20 4 2 2
## 21 4 3 33
## 22 4 4 13
## 23 4 5 38
## 24 4 6 44
## 25 5 1 22
## 26 5 2 2
## 27 5 3 71
## 28 5 4 11
## 29 5 5 4
## 30 5 6 2
## 31 6 1 9
## 32 6 2 1
## 33 6 3 14
## 34 6 4 1
## 35 6 5 2
## 36 6 6 3
Next, we conduct the configural frequency analysis and save the results. We then examine a summary of the results.
# Conduct configural frequency analysis and save the results
# Insert the response pattern frequency table
# and the name of the variables of interest (with a ~ and +)
<- CFA(cfa_disc2list, form = "~ listener + discloser")
results_disc2list
# Examine the saved results
summary(results_disc2list , showall = TRUE)
## function Call:
## -------------
## Formula: ~ listener + discloser
## Variables: discloser listener
## Categories: 6 6
##
## results of global tests:
## -----------------------
## pearson Chi-square test:
## Chi df pChi alpha
## 1 365.2749 25 0 0.05
##
## likelihood ratio test:
## Chi df pChi alpha
## 1 376.1141 25 0 0.05
##
## Information Criteria:
## loglik AIC BIC
## 1 -266.3476 554.6951 572.1139
##
## results of local tests:
## -----------------------
## Type (+) / Antitype (-) based on: z.pChi ;
## with Bonferroni adjusted alpha: 0.001388889
## pat. obs. exp. Type df z.Chi z.pChi
## 1 1 1 16 99.267 - 1 -8.357 0.000
## 2 1 2 8 4.530 . 1 1.630 0.052
## 3 1 3 119 56.231 + 1 8.371 0.000
## 4 1 4 33 14.969 + 1 4.660 0.000
## 5 1 5 24 26.097 . 1 -0.410 0.341
## 6 1 6 46 44.906 . 1 0.163 0.435
## 7 2 1 11 7.263 . 1 1.386 0.083
## 8 2 2 0 0.331 . 1 -0.576 0.282
## 9 2 3 5 4.114 . 1 0.437 0.331
## 10 2 4 0 1.095 . 1 -1.047 0.148
## 11 2 5 2 1.910 . 1 0.065 0.474
## 12 2 6 0 3.286 . 1 -1.813 0.035
## 13 3 1 790 727.148 . 1 2.331 0.010
## 14 3 2 33 33.183 . 1 -0.032 0.487
## 15 3 3 329 411.906 - 1 -4.085 0.000
## 16 3 4 94 109.649 . 1 -1.494 0.068
## 17 3 5 195 191.165 . 1 0.277 0.391
## 18 3 6 361 328.948 . 1 1.767 0.039
## 19 4 1 160 117.022 + 1 3.973 0.000
## 20 4 2 2 5.340 . 1 -1.445 0.074
## 21 4 3 33 66.289 - 1 -4.089 0.000
## 22 4 4 13 17.646 . 1 -1.106 0.134
## 23 4 5 38 30.765 . 1 1.304 0.096
## 24 4 6 44 52.938 . 1 -1.228 0.110
## 25 5 1 22 45.195 - 1 -3.450 0.000
## 26 5 2 2 2.062 . 1 -0.043 0.483
## 27 5 3 71 25.601 + 1 8.972 0.000
## 28 5 4 11 6.815 . 1 1.603 0.054
## 29 5 5 4 11.882 . 1 -2.287 0.011
## 30 5 6 2 20.445 - 1 -4.079 0.000
## 31 6 1 9 12.106 . 1 -0.893 0.186
## 32 6 2 1 0.552 . 1 0.602 0.274
## 33 6 3 14 6.857 . 1 2.728 0.003
## 34 6 4 1 1.825 . 1 -0.611 0.271
## 35 6 5 2 3.183 . 1 -0.663 0.254
## 36 6 6 3 5.476 . 1 -1.058 0.145
In the results, we can examine the column “Type” to determine which transitions occurred more (+) or less (-) frequently than expected. We can see that the transitions between (1) discloser acknowledgements and listener elaborations, (2) discloser acknowledgements and listener hedged disclosures, (3) discloser hedged disclosures and listener acknowledgements, and (4) discloser questions and listener elaborations occurred more frequently than expected. Furthermore, transitions between (1) discloser acknowledgements and listener acknowledgements, (2) discloser elaborations and listener elaborations, (3) discloser hedged disclosures and listener elaborations, (4) discloser questions and listener acknowledgements, and (5) discloser questions and listener reflections occurred less frequently than expected.
Add Hypothetical Experimental Condition to the Data.
One particular advantage of using configural frequency analysis is that it allows researchers to examine the association between 2+ categorical variables at a time. For instance, researchers may examine the association between gender, health status, and education (or any other combination of variables that you can think of!). Stemmler and colleagues’ work provide many examples of how to examine 2+ categorical variables using configural frequency analysis.
Here, we build on our current example examining turn-to-turn transitions by adding a hypothetical variable to the data set. Specifically, we add a variable called “condition” that indicates whether the conversation occurred in a face-to-face or computer-mediated setting and randomly assign a condition to each dyad.
# Create new variable called "condition" in the data set "data"
$condition <- NA
data
# Set seed for random number generator that will be used below (to make sure we get consistency across runs)
set.seed(1234)
# Randomly assign each dyad to a condition
<- # Select data
data %>%
data # Select grouping variable, in this case, dyad ID (id)
::group_by(id) %>%
dplyr# Create function that assigns a condition to each dyad
# Within mutate, assign the condition variable a random value between 0 and 1
# and round that value to an integer - i.e., 0 decimal places
::group_modify(function(.x, .y) .x %>% mutate(condition = round(runif(1, 0, 1), 0))) %>%
dplyr# Relabel the conditions
# If condition is equal to 0, relabel it as the face-to-face condition (FtF)
# If condition is equal to 1, relabel it as the computer-mediated communication condition (CMC)
::mutate(condition = ifelse(condition == 0, "FtF", ifelse(condition == 1, "CMC"))) %>%
dplyr# Save the data as a data.frame
as.data.frame()
# View the first 10 rows of the data
head(data, 10)
## id turn role turn_type lagged_turn_type condition
## 1 3 1 1 D_Elaboration <NA> FtF
## 2 3 2 2 L_Acknowledgement D_Elaboration FtF
## 3 3 3 1 D_HedgedDisclosure L_Acknowledgement FtF
## 4 3 4 2 L_Acknowledgement D_HedgedDisclosure FtF
## 5 3 5 1 D_HedgedDisclosure L_Acknowledgement FtF
## 6 3 6 2 L_Acknowledgement D_HedgedDisclosure FtF
## 7 3 7 1 D_Elaboration L_Acknowledgement FtF
## 8 3 8 2 L_Question D_Elaboration FtF
## 9 3 9 1 D_Elaboration L_Question FtF
## 10 3 10 2 L_Acknowledgement D_Elaboration FtF
Let’s double check to see how are random assignment worked. Specifically, we will count how many dyads ended up in each condition.
# Create dyad level data set
<- # Select data
dyad_data %>%
data # Select grouping variable, in this case, dyad ID (id)
::group_by(id) %>%
dplyr# Reduce each dyad to one row with its assigned condition
::summarise(assigned_condition = unique(condition)) %>%
dplyr# Count the number of dyads for each condition
::count(assigned_condition) %>%
dplyr# Save the data as a data.frame
as.data.frame()
# Print data set
dyad_data
## assigned_condition n
## 1 CMC 29
## 2 FtF 30
Woohoo - random assignment was successful! Twenty-nine dyads were assigned to the CMC condition, and 30 dyads were assigned to the FtF condition.
Now, we get back to preparing our data for configural frequency analysis. Like we did above, we generate a data frame containing transition frequencies by condition through cross-tabulation and save it to the data frame “data_dt3” (the 3 indicating our 3 variable analysis). Because there are 7 turn types (6 identified and 1 NA), 2 roles (listener and discloser), and 2 conditions (CMC and FtF) there are 28 turn transition/condition combinations in our dataset. Thus, the crosstab table contains 28 * 28 = 784 cells, representing all combinations.
# Reformat data frame to data table
<- data.table::as.data.table(data)
data_dt3
# Count the occurrence of lagged turn and turn pairs by condition
<- as.data.frame(with(data_dt3, table(turn_type, lagged_turn_type, condition)))
data_counts3
# Count the rows in data_counts
nrow(data_counts3)
## [1] 392
As described above, not all of the 784 cells are legitimate turn transition/condition combinations. Transitions that were at the beginning or end of the conversation and those that involved uncodable turns will need to be removed. In addition, while they exist in the table, D->D and L->L transitions do not occur in our data. We will remove them in the two code chunks below.
# Remove rows in which the lagged turn in the transition contains a _NA
<- data_counts3[ grep("_NA", data_counts3$lagged_turn_type, invert = TRUE) , ]
data_counts3
# Remove rows in which the following turn in the transition contains a _NA
<- data_counts3[ grep("_NA", data_counts3$turn_type, invert = TRUE) , ]
data_counts3
# Count the rows in data_counts
nrow(data_counts3)
## [1] 288
Since we will be examining listener –> discloser and discloser –> listener turn transitions separately, we will create two different data sets that contain the counts of these turn transitions. We will also remove the L->L and D->D transitions at this step.
# Create listener --> discloser transition data set
# Remove all transitions that begin with a discloser turn from data_counts
# by selecting all rows in lagged_turn_type with the discloser tag "D_"
<- data_counts3[ grep("D_", data_counts3$lagged_turn_type, invert = TRUE) , ]
list2disc3
# Remove all transitions that end with a listener turn to create the L->D subset
# by selecting all rows in turn_type with the listener tag "L_"
<- list2disc3[ grep("L_", list2disc3$turn_type, invert = TRUE) , ]
list2disc3 nrow(list2disc3)
## [1] 72
# View the first 10 rows of the data
head(list2disc3, 10)
## turn_type lagged_turn_type condition Freq
## 99 D_Acknowledgement L_Acknowledgement CMC 8
## 100 D_Advice L_Acknowledgement CMC 4
## 101 D_Elaboration L_Acknowledgement CMC 382
## 102 D_HedgedDisclosure L_Acknowledgement CMC 60
## 104 D_Question L_Acknowledgement CMC 15
## 105 D_Reflection L_Acknowledgement CMC 1
## 113 D_Acknowledgement L_Advice CMC 9
## 114 D_Advice L_Advice CMC 1
## 115 D_Elaboration L_Advice CMC 17
## 116 D_HedgedDisclosure L_Advice CMC 2
# Create discloser --> listener transition data set
# Remove all transitions that begin with a listener turn from data_counts
# by selecting all rows in lagged_turn_type with the listener tag "L_"
<- data_counts3[ grep("L_", data_counts3$lagged_turn_type, invert = TRUE) , ]
disc2list3
# Remove all transitions that end with a discloser turn to create the D->L subset
# by selecting all rows in turn_type with the discloser tag "D_"
<- disc2list3[ grep("D_", disc2list3$turn_type, invert = TRUE) , ]
disc2list3 nrow(disc2list3)
## [1] 72
# View the first 10 rows of the data
head(disc2list3, 10)
## turn_type lagged_turn_type condition Freq
## 8 L_Acknowledgement D_Acknowledgement CMC 5
## 9 L_Advice D_Acknowledgement CMC 7
## 10 L_Elaboration D_Acknowledgement CMC 61
## 11 L_HedgedDisclosure D_Acknowledgement CMC 19
## 13 L_Question D_Acknowledgement CMC 4
## 14 L_Reflection D_Acknowledgement CMC 15
## 22 L_Acknowledgement D_Advice CMC 6
## 23 L_Advice D_Advice CMC 0
## 24 L_Elaboration D_Advice CMC 3
## 25 L_HedgedDisclosure D_Advice CMC 0
Given that we are examining the transitions between six listener turn types and six discloser turn types by condition, we should expect each of our data sets to contain 72 rows. These rows represent all possible transitions, including a few transitions that were not observed in our dataset.
Finally, the confreq
package requires the data to be
organized in a specific way to conduct configural frequency analysis.
Specifically, each data set should have four columns that represent (1)
the type of lagged turn, (2) the current type of turn, (3) the
condition, and (4) the frequency of that combination. In the first three
columns, each turn type and condition needs to be represented by a
number instead of a category label. So, we number the turn categories in
alphabetical order (1 = acknowledgement, 2 = advice, 3 = elaboration, 4
= hedged disclosure, 5 = question, 6 = reflection) and the condition as
initially created above (0 = FtF, 1 = CMC). The code chunk below recodes
the turn labels into numbers.
# Recoding variables in listener --> discloser transition data set
<- # Select data
list2disc3 %>%
list2disc3 # Recode lagged turn and following turn variables with numbers
::mutate(lagged_turn_type = recode(list2disc3$lagged_turn_type,
dplyr"L_Acknowledgement" = 1,
"L_Advice" = 2,
"L_Elaboration" = 3,
"L_HedgedDisclosure" = 4,
"L_Question" = 5,
"L_Reflection" = 6),
turn_type = recode(list2disc3$turn_type,
"D_Acknowledgement" = 1,
"D_Advice" = 2,
"D_Elaboration" = 3,
"D_HedgedDisclosure" = 4,
"D_Question" = 5,
"D_Reflection" = 6),
condition = recode(list2disc3$condition,
"FtF" = 0,
"CMC" = 1)) %>%
# Save the data as a data.frame
as.data.frame()
# Recoding variables in discloser --> listener transition data set
<- # Select data
disc2list3 %>%
disc2list3 # Recode lagged turn and following turn variables with numbers
::mutate(lagged_turn_type = recode(disc2list3$lagged_turn_type,
dplyr"D_Acknowledgement" = 1,
"D_Advice" = 2,
"D_Elaboration" = 3,
"D_HedgedDisclosure" = 4,
"D_Question" = 5,
"D_Reflection" = 6),
turn_type = recode(disc2list3$turn_type,
"L_Acknowledgement" = 1,
"L_Advice" = 2,
"L_Elaboration" = 3,
"L_HedgedDisclosure" = 4,
"L_Question" = 5,
"L_Reflection" = 6),
condition = recode(disc2list3$condition,
"FtF" = 0,
"CMC" = 1)) %>%
# Save the data as a data.frame
as.data.frame()
Let’s reorder the values of the turn variables since they represent the turn categories in alphabetical order, and reorganize the columns so the lagged turns come first.
# Order data by lagged_turn_type and turn_type for listener --> discloser turn transitions
<- list2disc3[order(list2disc3$lagged_turn_type, list2disc3$turn_type), ]
list2disc3
# Reorder the columns for listener --> discloser turn transitions
<- list2disc3[, c(2, 1, 3, 4)]
list2disc3
# View the first 10 rows of the data
head(list2disc3, 10)
## lagged_turn_type turn_type condition Freq
## 99 1 1 1 8
## 295 1 1 0 20
## 100 1 2 1 4
## 296 1 2 0 4
## 101 1 3 1 382
## 297 1 3 0 385
## 102 1 4 1 60
## 298 1 4 0 96
## 104 1 5 1 15
## 300 1 5 0 13
# Order data by lagged_turn_type and turn_type for discloser --> listener turn transitions
<- disc2list3[order(disc2list3$lagged_turn_type, disc2list3$turn_type), ]
disc2list3
# Reorder the columns for discloser --> listener turn transitions
<- disc2list3[, c(2, 1, 3, 4)]
disc2list3
# View the first 10 rows of the data
head(disc2list3, 10)
## lagged_turn_type turn_type condition Freq
## 8 1 1 1 5
## 204 1 1 0 11
## 9 1 2 1 7
## 205 1 2 0 1
## 10 1 3 1 61
## 206 1 3 0 58
## 11 1 4 1 19
## 207 1 4 0 14
## 13 1 5 1 4
## 209 1 5 0 20
We can also rename the columns to represent the speaker of that turn.
# Rename columns in listener --> discloser turn transition data
colnames(list2disc3) <- c("listener", "discloser", "condition", "freq")
# Rename columns in discloser --> listener turn transition data
colnames(disc2list3) <- c("discloser", "listener", "condition", "freq")
Conduct the Configural Frequency Analysis with Three Variables.
As before, let’s examine the structure of the data sets.
We need to check whether the variables are in the correct format. Specifically, we need the variables that label the turn types of the listeners and disclosers as well as the condition variable to be factor variables (instead of integer variables). A factor variable makes sure R interprets the variables as categories instead of integers.
# Examine the structure of the listener --> discloser
# and discloser --> listener data
str(list2disc3)
## 'data.frame': 72 obs. of 4 variables:
## $ listener : num 1 1 1 1 1 1 1 1 1 1 ...
## $ discloser: num 1 1 2 2 3 3 4 4 5 5 ...
## $ condition: num 1 0 1 0 1 0 1 0 1 0 ...
## $ freq : int 8 20 4 4 382 385 60 96 15 13 ...
str(disc2list3)
## 'data.frame': 72 obs. of 4 variables:
## $ discloser: num 1 1 1 1 1 1 1 1 1 1 ...
## $ listener : num 1 1 2 2 3 3 4 4 5 5 ...
## $ condition: num 1 0 1 0 1 0 1 0 1 0 ...
## $ freq : int 5 11 7 1 61 58 19 14 4 20 ...
# Need the discloser, listener, and condition variables to be factors in both datasets
$listener <- as.factor(list2disc3$listener)
list2disc3$discloser <- as.factor(list2disc3$discloser)
list2disc3$condition <- as.factor(list2disc3$condition)
list2disc3
$listener <- as.factor(disc2list3$listener)
disc2list3$discloser <- as.factor(disc2list3$discloser)
disc2list3$condition <- as.factor(disc2list3$condition) disc2list3
Now that the data are in the correct format, we can run the configural frequency analyses.
Let’s first examine the listener to discloser transitions across conditions.
The configural frequency analysis function requires that the data are formatted as a response pattern frequency table.
# Change format of data for configural frequency analysis
# Insert data ("list2disc3") in the dat2fre(fre2dat()) function
<- dat2fre(fre2dat(list2disc3)) cfa_list2disc3
## Number of categories for each variable
## estimated from data are:
## listener discloser condition
## 6 6 2
## --> 72 different configurations
# Examine the response pattern frequency table
cfa_list2disc3
## listener discloser condition Freq
## 1 1 1 1 20
## 2 1 1 2 8
## 3 1 2 1 4
## 4 1 2 2 4
## 5 1 3 1 385
## 6 1 3 2 382
## 7 1 4 1 96
## 8 1 4 2 60
## 9 1 5 1 13
## 10 1 5 2 15
## 11 1 6 1 2
## 12 1 6 2 1
## 13 2 1 1 1
## 14 2 1 2 9
## 15 2 2 1 0
## 16 2 2 2 1
## 17 2 3 1 14
## 18 2 3 2 17
## 19 2 4 1 3
## 20 2 4 2 2
## 21 2 5 1 1
## 22 2 5 2 0
## 23 2 6 1 0
## 24 2 6 2 1
## 25 3 1 1 42
## 26 3 1 2 56
## 27 3 2 1 1
## 28 3 2 2 4
## 29 3 3 1 148
## 30 3 3 2 191
## 31 3 4 1 24
## 32 3 4 2 18
## 33 3 5 1 25
## 34 3 5 2 34
## 35 3 6 1 12
## 36 3 6 2 6
## 37 4 1 1 19
## 38 4 1 2 24
## 39 4 2 1 1
## 40 4 2 2 0
## 41 4 3 1 53
## 42 4 3 2 25
## 43 4 4 1 9
## 44 4 4 2 8
## 45 4 5 1 5
## 46 4 5 2 2
## 47 4 6 1 2
## 48 4 6 2 2
## 49 5 1 1 12
## 50 5 1 2 2
## 51 5 2 1 1
## 52 5 2 2 0
## 53 5 3 1 131
## 54 5 3 2 100
## 55 5 4 1 14
## 56 5 4 2 9
## 57 5 5 1 2
## 58 5 5 2 3
## 59 5 6 1 0
## 60 5 6 2 0
## 61 6 1 1 41
## 62 6 1 2 11
## 63 6 2 1 0
## 64 6 2 2 0
## 65 6 3 1 204
## 66 6 3 2 139
## 67 6 4 1 23
## 68 6 4 2 21
## 69 6 5 1 6
## 70 6 5 2 4
## 71 6 6 1 2
## 72 6 6 2 3
Next, we conduct the configural frequency analysis and save the results. We then examine a summary of the results.
# Conduct configural frequency analysis and save the results
# Insert the response pattern frequency table
# and the name of the variables of interest (with a ~ and +)
<- CFA(cfa_list2disc3, form = "~ listener + discloser + condition")
results_list2disc3
# Examine the saved results
summary(results_list2disc3 , showall = TRUE)
## function Call:
## -------------
## Formula: ~ listener + discloser + condition
## Variables: listener discloser condition
## Categories: 6 6 2
##
## results of global tests:
## -----------------------
## pearson Chi-square test:
## Chi df pChi alpha
## 1 405.9657 60 0 0.05
##
## likelihood ratio test:
## Chi df pChi alpha
## 1 384.5246 60 0 0.05
##
## Information Criteria:
## loglik AIC BIC
## 1 -325.6937 675.3875 702.7075
##
## results of local tests:
## -----------------------
## Type (+) / Antitype (-) based on: z.pChi ;
## with Bonferroni adjusted alpha: 0.0006944444
## pat. obs. exp. Type df z.Chi z.pChi
## 1 1 1 1 20 51.982 - 1 -4.436 0.000
## 2 1 1 2 8 45.899 - 1 -5.594 0.000
## 3 1 2 1 4 3.395 . 1 0.328 0.371
## 4 1 2 2 4 2.997 . 1 0.579 0.281
## 5 1 3 1 385 379.576 . 1 0.278 0.390
## 6 1 3 2 382 335.158 . 1 2.559 0.005
## 7 1 4 1 96 60.893 + 1 4.499 0.000
## 8 1 4 2 60 53.768 . 1 0.850 0.198
## 9 1 5 1 13 23.339 . 1 -2.140 0.016
## 10 1 5 2 15 20.608 . 1 -1.235 0.108
## 11 1 6 1 2 6.577 . 1 -1.785 0.037
## 12 1 6 2 1 5.808 . 1 -1.995 0.023
## 13 2 1 1 1 2.573 . 1 -0.981 0.163
## 14 2 1 2 9 2.272 + 1 4.464 0.000
## 15 2 2 1 0 0.168 . 1 -0.410 0.341
## 16 2 2 2 1 0.148 . 1 2.211 0.014
## 17 2 3 1 14 18.787 . 1 -1.104 0.135
## 18 2 3 2 17 16.589 . 1 0.101 0.460
## 19 2 4 1 3 3.014 . 1 -0.008 0.497
## 20 2 4 2 2 2.661 . 1 -0.405 0.343
## 21 2 5 1 1 1.155 . 1 -0.144 0.443
## 22 2 5 2 0 1.020 . 1 -1.010 0.156
## 23 2 6 1 0 0.326 . 1 -0.571 0.284
## 24 2 6 2 1 0.287 . 1 1.329 0.092
## 25 3 1 1 42 29.457 . 1 2.311 0.010
## 26 3 1 2 56 26.010 + 1 5.881 0.000
## 27 3 2 1 1 1.924 . 1 -0.666 0.253
## 28 3 2 2 4 1.699 . 1 1.766 0.039
## 29 3 3 1 148 215.093 - 1 -4.575 0.000
## 30 3 3 2 191 189.923 . 1 0.078 0.469
## 31 3 4 1 24 34.506 . 1 -1.789 0.037
## 32 3 4 2 18 30.468 . 1 -2.259 0.012
## 33 3 5 1 25 13.225 + 1 3.238 0.001
## 34 3 5 2 34 11.678 + 1 6.532 0.000
## 35 3 6 1 12 3.727 + 1 4.285 0.000
## 36 3 6 2 6 3.291 . 1 1.493 0.068
## 37 4 1 1 19 7.876 + 1 3.964 0.000
## 38 4 1 2 24 6.954 + 1 6.464 0.000
## 39 4 2 1 1 0.514 . 1 0.677 0.249
## 40 4 2 2 0 0.454 . 1 -0.674 0.250
## 41 4 3 1 53 57.512 . 1 -0.595 0.276
## 42 4 3 2 25 50.781 - 1 -3.618 0.000
## 43 4 4 1 9 9.226 . 1 -0.074 0.470
## 44 4 4 2 8 8.147 . 1 -0.051 0.480
## 45 4 5 1 5 3.536 . 1 0.778 0.218
## 46 4 5 2 2 3.122 . 1 -0.635 0.263
## 47 4 6 1 2 0.997 . 1 1.005 0.157
## 48 4 6 2 2 0.880 . 1 1.194 0.116
## 49 5 1 1 12 14.387 . 1 -0.629 0.265
## 50 5 1 2 2 12.703 . 1 -3.003 0.001
## 51 5 2 1 1 0.940 . 1 0.062 0.475
## 52 5 2 2 0 0.830 . 1 -0.911 0.181
## 53 5 3 1 131 105.054 . 1 2.531 0.006
## 54 5 3 2 100 92.761 . 1 0.752 0.226
## 55 5 4 1 14 16.853 . 1 -0.695 0.244
## 56 5 4 2 9 14.881 . 1 -1.525 0.064
## 57 5 5 1 2 6.459 . 1 -1.755 0.040
## 58 5 5 2 3 5.704 . 1 -1.132 0.129
## 59 5 6 1 0 1.820 . 1 -1.349 0.089
## 60 5 6 2 0 1.607 . 1 -1.268 0.102
## 61 6 1 1 41 23.838 + 1 3.515 0.000
## 62 6 1 2 11 21.049 . 1 -2.190 0.014
## 63 6 2 1 0 1.557 . 1 -1.248 0.106
## 64 6 2 2 0 1.375 . 1 -1.172 0.121
## 65 6 3 1 204 174.068 . 1 2.269 0.012
## 66 6 3 2 139 153.699 . 1 -1.186 0.118
## 67 6 4 1 23 27.925 . 1 -0.932 0.176
## 68 6 4 2 21 24.657 . 1 -0.736 0.231
## 69 6 5 1 6 10.703 . 1 -1.438 0.075
## 70 6 5 2 4 9.450 . 1 -1.773 0.038
## 71 6 6 1 2 3.016 . 1 -0.585 0.279
## 72 6 6 2 3 2.663 . 1 0.206 0.418
In the results, we can examine the column “Type” to determine which transitions occurred more (+) or less (-) frequently than expected.
For the face-to-face condition, we see that the transitions between (1) listener acknowledgements and discloser hedged disclosures, (2) listener elaborations and discloser questions, (3) listener elaborations and discloser reflections, (4) listener hedged disclosures and discloser acknowledgements, and (5) listener reflections and discloser acknowledgements occurred more frequently than expected. Furthermore, transitions between (1) listener acknowledgements and discloser acknowledgements and (2) listener elaborations and discloser elaborations occurred less frequently than expected.
For the computer-mediated communication condition, we see that the transitions between (1) listener advice and discloser acknowledgements, (2) listener elaborations and discloser acknowledgements, (3) listener elaborations and discloser questions, and (4) listener hedged disclosures and discloser acknowledgements occurred more frequently than expected. Furthermore, transitions between (1) listener acknowledgements and discloser acknowledgements and (2) listener hedged disclosures and discloser elaborations occurred less frequently than expected.
We next examine the discloser to listener transitions across conditions.
The configural frequency analysis function requires that the data are formatted as a response pattern frequency table.
# Change format of data for configural frequency analysis
# Insert data (disc2list3) in the dat2fre(fre2dat()) function
<- dat2fre(fre2dat(disc2list3)) cfa_disc2list3
## Number of categories for each variable
## estimated from data are:
## discloser listener condition
## 6 6 2
## --> 72 different configurations
# Examine the response pattern frequency table
cfa_disc2list3
## discloser listener condition Freq
## 1 1 1 1 11
## 2 1 1 2 5
## 3 1 2 1 1
## 4 1 2 2 7
## 5 1 3 1 58
## 6 1 3 2 61
## 7 1 4 1 14
## 8 1 4 2 19
## 9 1 5 1 20
## 10 1 5 2 4
## 11 1 6 1 31
## 12 1 6 2 15
## 13 2 1 1 5
## 14 2 1 2 6
## 15 2 2 1 0
## 16 2 2 2 0
## 17 2 3 1 2
## 18 2 3 2 3
## 19 2 4 1 0
## 20 2 4 2 0
## 21 2 5 1 1
## 22 2 5 2 1
## 23 2 6 1 0
## 24 2 6 2 0
## 25 3 1 1 400
## 26 3 1 2 390
## 27 3 2 1 14
## 28 3 2 2 19
## 29 3 3 1 145
## 30 3 3 2 184
## 31 3 4 1 63
## 32 3 4 2 31
## 33 3 5 1 107
## 34 3 5 2 88
## 35 3 6 1 214
## 36 3 6 2 147
## 37 4 1 1 97
## 38 4 1 2 63
## 39 4 2 1 1
## 40 4 2 2 1
## 41 4 3 1 15
## 42 4 3 2 18
## 43 4 4 1 8
## 44 4 4 2 5
## 45 4 5 1 21
## 46 4 5 2 17
## 47 4 6 1 27
## 48 4 6 2 17
## 49 5 1 1 15
## 50 5 1 2 7
## 51 5 2 1 1
## 52 5 2 2 1
## 53 5 3 1 25
## 54 5 3 2 46
## 55 5 4 1 8
## 56 5 4 2 3
## 57 5 5 1 3
## 58 5 5 2 1
## 59 5 6 1 2
## 60 5 6 2 0
## 61 6 1 1 5
## 62 6 1 2 4
## 63 6 2 1 0
## 64 6 2 2 1
## 65 6 3 1 8
## 66 6 3 2 6
## 67 6 4 1 1
## 68 6 4 2 0
## 69 6 5 1 1
## 70 6 5 2 1
## 71 6 6 1 3
## 72 6 6 2 0
Next, we conduct the configural frequency analysis and save the results. We then examine a summary of the results.
# Conduct configural frequency analysis and save the results
# Insert the response pattern frequency table
# and the name of the variables of interest (with a ~ and +)
<- CFA(cfa_disc2list3, form = "~ listener + discloser + condition")
results_disc2list3
# Examine the saved results
summary(results_disc2list3 , showall = TRUE)
## function Call:
## -------------
## Formula: ~ listener + discloser + condition
## Variables: discloser listener condition
## Categories: 6 6 2
##
## results of global tests:
## -----------------------
## pearson Chi-square test:
## Chi df pChi alpha
## 1 458.1574 60 0 0.05
##
## likelihood ratio test:
## Chi df pChi alpha
## 1 456.942 60 0 0.05
##
## Information Criteria:
## loglik AIC BIC
## 1 -359.3389 742.6778 769.9978
##
## results of local tests:
## -----------------------
## Type (+) / Antitype (-) based on: z.pChi ;
## with Bonferroni adjusted alpha: 0.0006944444
## pat. obs. exp. Type df z.Chi z.pChi
## 1 1 1 1 11 52.733 - 1 -5.747 0.000
## 2 1 1 2 5 46.534 - 1 -6.089 0.000
## 3 1 2 1 1 2.406 . 1 -0.907 0.182
## 4 1 2 2 7 2.124 + 1 3.346 0.000
## 5 1 3 1 58 29.872 + 1 5.147 0.000
## 6 1 3 2 61 26.360 + 1 6.747 0.000
## 7 1 4 1 14 7.952 . 1 2.145 0.016
## 8 1 4 2 19 7.017 + 1 4.524 0.000
## 9 1 5 1 20 13.863 . 1 1.648 0.050
## 10 1 5 2 4 12.234 . 1 -2.354 0.009
## 11 1 6 1 31 23.855 . 1 1.463 0.072
## 12 1 6 2 15 21.051 . 1 -1.319 0.094
## 13 2 1 1 5 3.859 . 1 0.581 0.281
## 14 2 1 2 6 3.405 . 1 1.406 0.080
## 15 2 2 1 0 0.176 . 1 -0.420 0.337
## 16 2 2 2 0 0.155 . 1 -0.394 0.347
## 17 2 3 1 2 2.186 . 1 -0.126 0.450
## 18 2 3 2 3 1.929 . 1 0.771 0.220
## 19 2 4 1 0 0.582 . 1 -0.763 0.223
## 20 2 4 2 0 0.513 . 1 -0.717 0.237
## 21 2 5 1 1 1.014 . 1 -0.014 0.494
## 22 2 5 2 1 0.895 . 1 0.111 0.456
## 23 2 6 1 0 1.746 . 1 -1.321 0.093
## 24 2 6 2 0 1.540 . 1 -1.241 0.107
## 25 3 1 1 400 386.279 . 1 0.698 0.243
## 26 3 1 2 390 340.869 . 1 2.661 0.004
## 27 3 2 1 14 17.628 . 1 -0.864 0.194
## 28 3 2 2 19 15.556 . 1 0.873 0.191
## 29 3 3 1 145 218.815 - 1 -4.990 0.000
## 30 3 3 2 184 193.091 . 1 -0.654 0.256
## 31 3 4 1 63 58.248 . 1 0.623 0.267
## 32 3 4 2 31 51.401 . 1 -2.846 0.002
## 33 3 5 1 107 101.552 . 1 0.541 0.294
## 34 3 5 2 88 89.613 . 1 -0.170 0.432
## 35 3 6 1 214 174.745 . 1 2.970 0.001
## 36 3 6 2 147 154.203 . 1 -0.580 0.281
## 37 4 1 1 97 62.165 + 1 4.418 0.000
## 38 4 1 2 63 54.857 . 1 1.099 0.136
## 39 4 2 1 1 2.837 . 1 -1.091 0.138
## 40 4 2 2 1 2.503 . 1 -0.950 0.171
## 41 4 3 1 15 35.214 - 1 -3.406 0.000
## 42 4 3 2 18 31.075 . 1 -2.345 0.010
## 43 4 4 1 8 9.374 . 1 -0.449 0.327
## 44 4 4 2 5 8.272 . 1 -1.138 0.128
## 45 4 5 1 21 16.343 . 1 1.152 0.125
## 46 4 5 2 17 14.422 . 1 0.679 0.249
## 47 4 6 1 27 28.122 . 1 -0.212 0.416
## 48 4 6 2 17 24.816 . 1 -1.569 0.058
## 49 5 1 1 15 24.008 . 1 -1.839 0.033
## 50 5 1 2 7 21.186 . 1 -3.082 0.001
## 51 5 2 1 1 1.096 . 1 -0.091 0.464
## 52 5 2 2 1 0.967 . 1 0.034 0.487
## 53 5 3 1 25 13.600 . 1 3.091 0.001
## 54 5 3 2 46 12.001 + 1 9.814 0.000
## 55 5 4 1 8 3.620 . 1 2.302 0.011
## 56 5 4 2 3 3.195 . 1 -0.109 0.457
## 57 5 5 1 3 6.312 . 1 -1.318 0.094
## 58 5 5 2 1 5.570 . 1 -1.936 0.026
## 59 5 6 1 2 10.861 . 1 -2.689 0.004
## 60 5 6 2 0 9.584 . 1 -3.096 0.001
## 61 6 1 1 5 6.431 . 1 -0.564 0.286
## 62 6 1 2 4 5.675 . 1 -0.703 0.241
## 63 6 2 1 0 0.293 . 1 -0.542 0.294
## 64 6 2 2 1 0.259 . 1 1.456 0.073
## 65 6 3 1 8 3.643 . 1 2.283 0.011
## 66 6 3 2 6 3.215 . 1 1.554 0.060
## 67 6 4 1 1 0.970 . 1 0.031 0.488
## 68 6 4 2 0 0.856 . 1 -0.925 0.177
## 69 6 5 1 1 1.691 . 1 -0.531 0.298
## 70 6 5 2 1 1.492 . 1 -0.403 0.344
## 71 6 6 1 3 2.909 . 1 0.053 0.479
## 72 6 6 2 0 2.567 . 1 -1.602 0.055
In the results, we can examine the column “Type” to determine which transitions occurred more (+) or less (-) frequently than expected.
For the face-to-face condition, we see that the transitions between (1) discloser acknowledgements and listener elaborations and (2) discloser hedged disclosures and listener acknowledgements occurred more frequently than expected. Furthermore, transitions between (1) discloser acknowledgements and listener acknowledgements, (2) discloser elaborations and listener elaborations, and (3) discloser hedged disclosures and listener elaborations occurred less frequently than expected.
For the computer-mediated communication condition, we see that the transitions between (1) discloser acknowledgements and listener advice, (2) discloser acknowledgements and listener elaborations, (3) discloser acknowledgements and listener hedged disclosures, and (4) discloser questions and listener elaborations occurred more frequently than expected. Furthermore, transitions between discloser acknowledgements and listener acknowledgements occurred less frequently than expected.
Additional Information
We created this tutorial with a system environment and versions of R and packages that might be different from yours. If R reports errors when you attempt to run this tutorial, running the code chunk below and comparing your output and the tutorial posted on the LHAMA website may be helpful.
session_info(pkgs = c("attached"))
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.2.0 (2022-04-22)
## os macOS Big Sur/Monterey 10.16
## system x86_64, darwin17.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/New_York
## date 2023-06-16
## pandoc 2.18 @ /Applications/RStudio.app/Contents/MacOS/quarto/bin/tools/ (via rmarkdown)
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## confreq * 1.5.6-7 2022-04-12 [1] CRAN (R 4.2.0)
## data.table * 1.14.2 2021-09-27 [1] CRAN (R 4.2.0)
## devtools * 2.4.3 2021-11-30 [1] CRAN (R 4.2.0)
## dplyr * 1.0.9 2022-04-28 [1] CRAN (R 4.2.0)
## forcats * 0.5.1 2021-01-27 [1] CRAN (R 4.2.0)
## ggplot2 * 3.3.6 2022-05-03 [1] CRAN (R 4.2.0)
## gmp * 0.6-5 2022-03-17 [1] CRAN (R 4.2.0)
## purrr * 0.3.4 2020-04-17 [1] CRAN (R 4.2.0)
## readr * 2.1.2 2022-01-30 [1] CRAN (R 4.2.0)
## stringr * 1.4.0 2019-02-10 [1] CRAN (R 4.2.0)
## tibble * 3.1.7 2022-05-03 [1] CRAN (R 4.2.0)
## tidyr * 1.2.0 2022-02-01 [1] CRAN (R 4.2.0)
## tidyverse * 1.3.1 2021-04-15 [1] CRAN (R 4.2.0)
## usethis * 2.1.5 2021-12-09 [1] CRAN (R 4.2.0)
## vcd * 1.4-10 2022-06-09 [1] CRAN (R 4.2.0)
##
## [1] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
##
## ──────────────────────────────────────────────────────────────────────────────