Skip to contents

pipeline status coverage report

What is ONA?

Ordered Network Analysis (ONA) extends Epistemic Network Analysis to model directed connections — capturing not just which codes co-occur, but the temporal order in which they appear within a conversational window. Each connection from code A to code B represents A appearing in context (prior rows) when B is observed, making the network asymmetric and directional.

ONA builds on rENA and tma for accumulation, and libqe for the underlying C++ math.


Installation

Development version

install.packages("ona", repos = c("https://cran.qe-libs.org", "https://cran.rstudio.org"))

Quick Start

library(ona)

codes        <- c("Data", "Technical.Constraints", "Performance.Parameters",
                  "Client.and.Consultant.Requests", "Design.Reasoning", "Collaboration")
units        <- c("UserName", "Condition", "GroupName")
conversation <- c("Condition", "GroupName")

# Simple form
ona_model <- RS.data |>
  accumulate(units, codes, conversation, default_window = 4, ordered = TRUE) |>
  model()

# Granular form (equivalent)
ona_model <- RS.data |>
  accumulate(units, codes, conversation, default_window = 4, ordered = TRUE) |>
  sphere_norm() |>
  center(exclude_zero_networks = TRUE) |>
  rotate() |>
  project() |>
  optimize()

Advanced: HOO-rule accumulation with tma

Use tma when you need conversation rules that go beyond simple windowing — e.g. units whose window resets based on group membership or other conditions.

library(ona)
library(tma)
library(data.table)

rs_dat <- as.data.table(tma::RS.data)

codes    <- c("Data", "Technical.Constraints", "Performance.Parameters",
              "Client.and.Consultant.Requests", "Design.Reasoning", "Collaboration")
units.by <- c("Condition", "UserName")

hoo_rules <- tma::conversation_rules(
  (Condition == UNIT$Condition & GroupName == UNIT$GroupName & UserName == UNIT$UserName)
)

ona_model <- tma::contexts(rs_dat, units_by = units.by, hoo_rules = hoo_rules) |>
  tma::accumulate_contexts(codes = codes, return.ena.set = FALSE, norm.by = NULL) |>
  model()

Accessing Results

ona_model$points                  # unit positions in ONA space
ona_model$line.weights            # normalised adjacency vectors (units × connections)
ona_model$connection.counts       # raw directed co-occurrence counts
ona_model$rotation$nodes          # code node positions
ona_model$model$centroids         # unit centroids
ona_model$model$variance          # variance explained per dimension

Rotation Methods

Rotation Function
SVD (default) model(rotate.using = "svd")
Means model(rotate.using = "mean")
Custom matrix model(rotation.set = my_rotation_set)
# Means rotation
ona_model <- RS.data |>
  accumulate(units, codes, conversation, default_window = 4, ordered = TRUE) |>
  model(rotate.using = "mean")

Key Differences from rENA

rENA ONA
Network type Undirected (symmetric) Directed (asymmetric)
Connection matrix Upper triangle Full square (n² columns)
Accumulation rENA::accumulate() tma::accumulate_contexts()
Node positions lws_lsq_positions directed_node_positions
Zero-network exclusion Optional Always applied