| Title: | Topological Sort-Based Hierarchy Inference |
|---|---|
| Description: | Deciphering hierarchy of agents exhibiting observable dominance events is a crucial problem in several disciplines, in particular in behavioural analysis of social animals, but also in social sciences and game theory. This package implements an inference approach based on graph theory, namely to extract the optimal acyclic subset of a weighted graph of dominance; this allows for hierarchy estimation through topological sorting. The package also contains infrastructure to investigate partially defined hierarchies and hierarchy dynamics. |
| Authors: | Miron B. Kursa [aut, cre] (ORCID: <https://orcid.org/0000-0001-7672-648X>) |
| Maintainer: | Miron B. Kursa <[email protected]> |
| License: | GPL-3 |
| Version: | 1.0.0 |
| Built: | 2026-05-13 06:27:40 UTC |
| Source: | https://gitlab.com/mbq/toporanga |
Some toporanga graphs can be topologically sorted in many ways, but arrange will generate only one, random order.
This function allows to list all of them.
Use sample_toposort to fairly sample a single toposort.
all_toposorts(x, ..., limit = Inf)all_toposorts(x, ..., limit = Inf)
x |
a |
... |
ignored. |
limit |
maximal number of permutations returned; function errors when exhausted. |
A list of possible orderings, in a form of vectors of agent IDs.
Estimate agent hierarchy from a tally by assembling edges in order of decreasing weight and skipping cycle-creating ones. The effect is a directed acyclic graph that can be topologically-sorted into an agent order, though this order may not be unique depending on how well the latent hierarchy is sampled and whether it even exists.
arrange(tally)arrange(tally)
tally |
a |
A toporanga_graph object, representing the established graph.
The method may be stochastic if there are ties in weights.
data(EcoHAB) arrange(tally_log(EcoHAB$winner,EcoHAB$loser))data(EcoHAB) arrange(tally_log(EcoHAB$winner,EcoHAB$loser))
Decomposes the tally into stronly connected components.
components(tally)components(tally)
tally |
a |
A vector of component IDs for each agent, named with agent IDs. Components are integers from 1 up to the component count, which is at most the number of agents. Hence, when the tally is fully strongly connected, the result is a vector of ones.
Splits the event log into cumulative epochs, i.e., starting from the start up to selected number of final points.
Returns an object which has to be fed into epochs argument of toporanga function.
cumulative_epochs(n, t)cumulative_epochs(n, t)
n |
number of epochs. Silently capped to the number of events, if larger. |
t |
optional event times, vector of a same length and order as the event log given to |
A special function that can be passed to the epochs argument of toporanga function.
If time is not given, event log must be sorted; otherwise, epochs will not make any sense.
Uses the Schulze / widest path approach to re-express indirect domination into direct one.
For instance, if and both have weight 10, but has weight 3, it is gonna be corrected to 10 by this function.
diffuse(tally, blend)diffuse(tally, blend)
tally |
a |
blend |
a numerical factor to limit the effect of diffusion; weight of indirect path is multiplied by the given factor, while direct weights are not changed.
When set to 1, function behaves the same as |
A modified toporanga_tally object.
Produces a string vector with the dot code that can be used to plot dominance graph with Graphviz or transfer topology to other software.
dot(x, con, ..., reduce = TRUE)dot(x, con, ..., reduce = TRUE)
x |
a |
con |
if given, code is pushed to the given connection instead of returned; this can simply be a file name. |
... |
ignored. |
reduce |
if |
Graphviz dot code of the graph, invisibly when con is given.
Mice dominance events recorded by the Eco-HAB system.
Covers a group of 10 mice and 6575 events recorded over a span of almost 5 days, corresponding to followings in the system.
Contains three columns: winner, ID of winning mouse, loser, ID of a losing mice, t time of event occurrence, in seconds since the first event.
data(EcoHAB)data(EcoHAB)
An object of class data.frame with 6575 rows and 3 columns.
When we have and , this function will change to and to .
marginise(tally)marginise(tally)
tally |
a |
A modified toporanga_tally object.
When we have and , this function will normalise both to sum to 1, i.e. divide by .
This way dominance matters more than engagement in conflicts between particular agents; in particular, an agent that frequently loses in typical events but always dominate over the otherwise dominating agent will come on top with normalised weights, while remain near the bottom otherwise.
normalise(tally)normalise(tally)
tally |
a |
A modified toporanga_tally object.
Pull numerical descriptors of a toporanga graph.
parameters(g)parameters(g)
g |
|
A data.frame object.
Each of its rows corresponds to one agent.
This agent's ID is listed in the Agent column.
Superiors counts the number of agents which are upstream from a given agent, while Subordinates counts those downstream.
This numbers correspond to a rank when when there is only one unique toposort of the dominance graph, and provide a graceful degradation if not.
In particular they do not depend on random seed or the default toposort stored in the graph object.
Thus, subordinate count is a recommended outcome if a single dominance score of an agent is desired.
The Order column notes the aforementioned default toposort, which can be re-sampled with the sample_toposort.
Additional columns may appear depending on meta-data in the graph object, in particular epoch parameters when using epoch argument of toporanga function.
Some toporanga graphs can be topologically sorted in many ways, but arrange will generate only one, random order.
This function allows one to switch it to an another, randomly sampled one.
Use all_toposorts to calculate all possible orderings.
sample_toposort(x)sample_toposort(x)
x |
a toporanga graph. |
The same graph, with a fairly re-sampled default order.
Creates a toporanga_tally objects from a matrix representing counts of domination events between pairs of agents.
tally_from_matrix(x)tally_from_matrix(x)
x |
matrix to convert. It must be square, have zero diagonal, non-negative values and identical column and row names or lack of both ("1".."n" is gonna be inferred in this case). |
toporanga_tally object.
If in doubt, use tally_log instead of this function.
Collects a log of domination events into a toporanga_tally object which can be fed to other functions in the package.
tally_log(winning, opposing, weight, ..., agents)tally_log(winning, opposing, weight, ..., agents)
winning |
vector of IDs of winning agents. |
opposing |
vector of IDs of opposing agents. |
weight |
optional weight of the event; set to 1 for each event if not given. |
... |
ignored. |
agents |
optional vector ofg IDs of all agents; allows for ghost agents that are in the set but are not involved in any event. |
A toporanga_tally object.
The general pipeline of toporanga is to tally the domination events, optionally modify the tally by diffusing event weights and/or re-scoring reciprocal weights, arrange agents into an order represented by an acyclic graph, finally to reduce it to an order or a dominance score. This function collects all of this into a single call.
toporanga( winning, opposing, weight, ..., agents, diffuse = FALSE, reciprocals = c(), output = c("parameters", "graph", "order_sample", "subordinate_count"), epochs )toporanga( winning, opposing, weight, ..., agents, diffuse = FALSE, reciprocals = c(), output = c("parameters", "graph", "order_sample", "subordinate_count"), epochs )
winning |
vector of IDs of winning agents. |
opposing |
vector of IDs of opposing agents. |
weight |
optional weight of the event; set to 1 for each event if not given. |
... |
ignored. |
agents |
optional vector of IDs of all agents; allows for ghost agents that are in the set but are not involved in any event. |
diffuse |
if |
reciprocals |
a vector of commands applied to the tally.
|
output |
specifies what to return from the function.
|
epochs |
optional driver for applying analysis on subsets of events. See |
A result of the caclulation in a form specified by the output argument, aggregated over epochs is epochs argument is given.
data(EcoHAB) toporanga(EcoHAB$winner,EcoHAB$loser)data(EcoHAB) toporanga(EcoHAB$winner,EcoHAB$loser)
Splits the event log into cumulative epochs, i.e., starting from the start up to selected number of final points.
Returns an object which has to be fed into epochs argument of toporanga function.
window_epochs(n, window, t)window_epochs(n, window, t)
n |
number of epochs.
Silently capped to the number of events, if larger.
Inferred from |
window |
size of the moving window; if |
t |
optional event times, vector of a same length and order as the event log given to |
A special function that can be passed to the epochs argument of toporanga function.
If time is not given, event log must be sorted; otherwise, epochs will not make any sense.
When we have and , this function will retain and change into .
zero_opposition(tally, quench = FALSE)zero_opposition(tally, quench = FALSE)
tally |
a |
quench |
whether to remove tied-up weights. |
A modified toporanga_tally object.