dyadicMarkov workflow

This vignette illustrates a minimal workflow with dyadicMarkov. We compute empirical transition counts, estimate transition probabilities by maximum likelihood and classify univariate and bivariate dependence structures.

Create toy dyadic chains

We begin with two deterministic toy state sequences for the two members of a dyad.

chainFM <- c(
  1L,2L,1L,2L,2L,1L,  1L,1L,2L,2L,1L,2L,
  2L,1L,1L,2L,1L,2L,  1L,2L,2L,1L,2L,1L
)
chainSM <- c(
  2L,1L,2L,1L,1L,2L,  2L,2L,1L,1L,2L,1L,
  1L,2L,2L,1L,2L,1L,  2L,1L,1L,2L,1L,2L
)

length(chainFM)
#> [1] 24
head(chainFM)
#> [1] 1 2 1 2 2 1
length(chainSM)
#> [1] 24
head(chainSM)
#> [1] 2 1 2 1 1 2

Compute empirical transition counts

We convert the observed dyadic sequences into empirical transition counts. These counts are the sufficient statistics used by the estimation procedure. For states = 2, the empirical count matrix has states^2 = 4 rows, corresponding to the current dyadic states (FM_t, SM_t), and states = 2 columns, corresponding to the next state of the first member FM_{t+1}.

states <- 2L
emp <- dyadicMarkov::countEmp(chainFM = chainFM, chainSM = chainSM, states = states)
emp
#>      [,1] [,2]
#> [1,]    0    0
#> [2,]    3    8
#> [3,]    8    4
#> [4,]    0    0

Maximum likelihood estimation

We estimate the transition probabilities by maximum likelihood. If a row has zero empirical counts, the function applies a uniform normalization so that the resulting row remains a valid probability vector.

fit <- dyadicMarkov::mleEstimation(emp)
fit
#>           [,1]      [,2]
#> [1,] 0.5000000 0.5000000
#> [2,] 0.2727273 0.7272727
#> [3,] 0.6666667 0.3333333
#> [4,] 0.5000000 0.5000000
rowSums(fit)
#> [1] 1 1 1 1

Classify the univariate pattern

Using the observed chains, we classify the univariate interaction pattern at a chosen significance level.

pat <- dyadicMarkov::univariatePattern(
  chainFM = chainFM,
  chainSM = chainSM,
  states  = 2L,
  alpha   = 0.05
)

pat[["pattern"]]
#> [1] "IM (A0)"
pat[["TEST.AM"]]
#> 
#>  Chi-squared test, Actor-only model
#> 
#> data:  Observed vs Estimated
#> X-squared = 0, df = 2, p-value = 1
#> alternative hypothesis: The unrestricted model fits the data better
pat[["TEST.PM"]]
#> 
#>  Chi-squared test, Partner-only model
#> 
#> data:  Observed vs Estimated
#> X-squared = 0, df = 2, p-value = 1
#> alternative hypothesis: The unrestricted model fits the data better

Classify the bivariate dependence case

We now illustrate the first step of the bivariate workflow. Suppose that two categorical variables are observed repeatedly for both members of the dyad. We first compute the empirical bivariate transition counts and then test which dependence case is supported by the data.

chainFM_V1 <- chainFM
chainSM_V1 <- chainSM

chainFM_V2 <- c(
  1L,1L,2L,2L,1L,2L,  2L,1L,1L,2L,1L,2L,
  1L,2L,1L,2L,2L,1L,  2L,2L,1L,1L,2L,1L
)
chainSM_V2 <- c(
  2L,2L,1L,1L,2L,1L,  1L,2L,2L,1L,2L,1L,
  2L,1L,2L,1L,1L,2L,  1L,1L,2L,2L,1L,2L
)

emp2 <- dyadicMarkov::countEmpBivariate(
  chainFM_V1, chainSM_V1,
  chainFM_V2, chainSM_V2,
  states = 2L
)

emp2
#>       [,1] [,2]
#>  [1,]    0    0
#>  [2,]    0    0
#>  [3,]    0    0
#>  [4,]    0    0
#>  [5,]    0    0
#>  [6,]    0    5
#>  [7,]    3    3
#>  [8,]    0    0
#>  [9,]    0    0
#> [10,]    5    1
#> [11,]    3    3
#> [12,]    0    0
#> [13,]    0    0
#> [14,]    0    0
#> [15,]    0    0
#> [16,]    0    0

dyadicMarkov::bivariateCase(emp2, alpha = 0.05)
#> $testUnivariate
#> 
#>  Chi-squared test
#> 
#> data:  Observed vs Estimated
#> X-squared = 4.9375, df = 12, p-value = 0.96
#> alternative hypothesis: The unrestricted model fits the data better
#> 
#> 
#> $testPartial
#> 
#>  Chi-squared test
#> 
#> data:  Observed vs Estimated
#> X-squared = 7.6389, df = 12, p-value = 0.8127
#> alternative hypothesis: The unrestricted model fits the data better
#> 
#> 
#> $case
#> [1] "trivial"

In this example, the bivariate procedure selects the trivial case, indicating that the observed dynamics can be represented by the simplest dependence structure considered by the method.