---
title: "Network Perception Analysis"
author: "Sima Najafzadehkhoei"
date: today
vignette: >
  %\VignetteIndexEntry{Network Perception Analysis}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
---

# Imaginary Network Motifs: Testing Systematic Perception Errors

People do not perceive social networks randomly---their errors follow
systematic patterns (Tanaka & Vega Yon, 2023). This vignette demonstrates
how to use `imaginarycss` to (1) compute observed imaginary-census motif
counts, (2) generate a null distribution that preserves each perceiver's
tie-level accuracy, and (3) test which motif patterns are significantly
elevated or reduced relative to chance.

## Setup

```{r}
#| label: setup
#| message: false
library(imaginarycss)

# Load Krackhardt data
data(krackhardt_advice)
data(krackhardt_friendship)
data(krackhardt_friendship_perceptions)
data(krackhardt_advice_perceptions)

# Convert edge-list data frames to adjacency matrices
df_to_adjmat <- function(df) {
  n <- max(c(df$from, df$to))
  m <- matrix(0L, nrow = n, ncol = n)
  m[cbind(df$from, df$to)] <- df$value
  m
}

advice_matrix     <- df_to_adjmat(krackhardt_advice)
friendship_matrix <- df_to_adjmat(krackhardt_friendship)
```

## Data Overview

```{r}
#| label: data-overview
n <- nrow(advice_matrix)

# Network summary
data.frame(
  Network    = c("Friendship", "Advice"),
  Edges      = c(sum(friendship_matrix), sum(advice_matrix)),
  Density    = round(c(
    sum(friendship_matrix) / (n * (n - 1)),
    sum(advice_matrix)     / (n * (n - 1))
  ), 3)
)
```

## Creating the CSS Graphs

Each graph bundles the true network (first element) with every individual's
perception.

```{r}
#| label: graphs
friendship_graph <- new_barry_graph(
  c(list(friendship_matrix), krackhardt_friendship_perceptions)
)
advice_graph <- new_barry_graph(
  c(list(advice_matrix), krackhardt_advice_perceptions)
)
```

## Observed Motif Counts

The imaginary census classifies every perceiver--dyad pair into one of ten
categories. The `summary()` method aggregates counts across perceivers.

```{r}
#| label: observed
friendship_observed <- count_imaginary_census(friendship_graph)
advice_observed     <- count_imaginary_census(advice_graph)

# Friendship motifs (top 6)
head(summary(friendship_observed))

# Advice motifs (top 6)
head(summary(advice_observed))
```

## Null-Model Testing

The `test_imaginary_census()` function generates null CSS samples for each
network. Each sample preserves every perceiver's four accuracy rates
(true-positive/true-negative for ego/alter dyads) but randomises which
specific dyads are misperceived. It then computes z-scores and two-sided
empirical p-values.

```{r}
#| label: test
#| fig.height: 7
#| fig.width: 8
set.seed(331)
friendship_test <- test_imaginary_census(friendship_graph, n_sim = 100)
advice_test     <- test_imaginary_census(advice_graph, n_sim = 100)
```

## Results

The `plot()` method for `imaginarycss_test` objects shows a horizontal
barplot of z-scores for each motif. Motifs whose z-score exceeds the
critical threshold (dashed red lines) are coloured steelblue; those
within the expected range under the null model are shown in grey.

```{r}
#| label: results
#| fig.height: 7
#| fig.width: 8
# Print significant motifs
friendship_test
advice_test

# Visualise z-scores
plot(friendship_test, main = "Friendship: Motif Z-Scores vs Null")
plot(advice_test,     main = "Advice: Motif Z-Scores vs Null")
```

## Full Summary

The `summary()` method shows all motifs with their test statistics.

```{r}
#| label: summary
summary(friendship_test)
```

## Tie-Level Accuracy

```{r}
#| label: accuracy
friendship_acc <- tie_level_accuracy(friendship_graph)
advice_acc     <- tie_level_accuracy(advice_graph)

# Mean individual accuracy
data.frame(
  Network = c("Friendship", "Advice"),
  TP      = round(c(
    mean(friendship_acc$p_1_ego, na.rm = TRUE),
    mean(advice_acc$p_1_ego,     na.rm = TRUE)
  ), 3),
  TN      = round(c(
    mean(friendship_acc$p_0_ego, na.rm = TRUE),
    mean(advice_acc$p_0_ego,     na.rm = TRUE)
  ), 3)
)
```

## Conclusion

By comparing observed motif counts against null distributions that preserve
individual-level accuracy, the imaginary census reveals *which* perceptual
errors are systematic rather than random. Elevated motifs indicate cognitive
schemas (e.g., balance, reciprocity) that distort network perception beyond
what individual accuracy rates alone would predict.
