aggregate_edges: Aggregate Duplicate Edges After Folding

View source: R/aggregate_edges.R

aggregate_edgesR Documentation

Aggregate Duplicate Edges After Folding

Description

Collapses duplicate 'from -> to' rows in an edge list using explicit, per-column aggregation semantics. This is the post-fold aggregation step intended to run *after* redirect / canonical folding has coalesced URL variants onto their representatives, and it is a loss-aware alternative to [get_unique_edges()].

Where [get_unique_edges()] dedups a 'from/to' pair by **keeping the first row** (silently discarding everything else on the duplicate rows), 'aggregate_edges()' combines the duplicate rows column-by-column. This matters the moment edges carry quantities: click counts, predicted click propensities, repeated links to the same destination, and conflicting follow / nofollow metadata are all preserved or combined deterministically instead of dropped.

Usage

aggregate_edges(
  edge_list_df,
  agg = list(),
  nofollow_policy = c("any", "all", "majority", "error"),
  preserve_cols = character(0),
  self_loops = c("drop", "keep"),
  from_col = "from",
  to_col = "to"
)

Arguments

edge_list_df

A data frame representing the edge list, with at least the 'from_col' and 'to_col' columns.

agg

A named list of per-column aggregation overrides. Names are column names; values are either a built-in aggregation string or a function. Columns not listed use the defaults described above. Default 'list()'.

nofollow_policy

The default conflict policy applied to logical columns that are not explicitly listed in 'agg'. One of '"any"' (default), '"all"', '"majority"', or '"error"'. Named 'nofollow_policy' because the nofollow flag is the canonical boolean attribute, but it governs every un-overridden logical column.

preserve_cols

Character vector of columns to keep un-collapsed as per-group list-columns (e.g. placement / position features). Default 'character(0)'.

self_loops

How to handle self-loops ('a -> a'). One of '"drop"' (default) or '"keep"'.

from_col

Name of the source-node column. Default '"from"'.

to_col

Name of the target-node column. Default '"to"'.

Details

## Default per-column semantics

For every column other than 'from_col' / 'to_col' (and any column named in 'preserve_cols'), an aggregation is chosen automatically unless overridden in 'agg':

- **numeric / integer columns** (additive counts and click propensities) are summed. Repeated link instances to the same destination therefore add their propensities together: multiple slots pointing at one target produce more total propensity, which is the correct behavioral reading. - **logical columns** (boolean attributes such as 'nofollow') are resolved with an explicit *conflict policy* (see 'nofollow_policy'). They are never silently first-wins. - **all other columns** (character, factor, ...) fall back to '"first"', which reproduces the legacy keep-first behavior for non-additive identifier-like columns.

## Overriding per column

'agg' is a named list mapping a column name to either:

- one of the built-in strings '"sum"', '"mean"', '"max"', '"min"', '"first"', '"last"', '"any"', '"all"', '"majority"', or '"error"', or - a function taking the vector of grouped values and returning a length-1 value.

The boolean conflict policies ('"any"', '"all"', '"majority"', '"error"') may be applied to any logical column. '"error"' raises if a 'from/to' group holds conflicting (mixed 'TRUE'/'FALSE') values; the others reduce to "any TRUE", "all TRUE", and the majority value (ties resolve to 'TRUE') respectively.

## Preserving placement features

Columns named in 'preserve_cols' are **not** collapsed. Each surviving 'from/to' group keeps the individual per-instance values as a list-column (one list element per group, holding that group's vector of values). This lets placement / position features survive aggregation so a later reasonable-surfer model can use each individual link instance.

## Backward compatibility

With no weight or extra columns (a plain 'from'/'to' edge list), the result is identical to [get_unique_edges()]: NA edges dropped, self-loops handled per 'self_loops', one row per unique 'from/to' pair, from/to coerced to character.

Value

A data frame with one row per unique 'from/to' pair (self-loops handled per 'self_loops'). 'from_col' / 'to_col' are coerced to character; each remaining column is aggregated per its resolved rule; 'preserve_cols' become list-columns. Row order follows first appearance of each 'from/to' pair in the (NA-filtered, self-loop-handled) input.

See Also

[get_unique_edges()] for the lossy keep-first dedup.

Examples

# Click counts to the same destination sum instead of being dropped.
edges <- data.frame(
  from = c("A", "A", "B"),
  to = c("B", "B", "C"),
  clicks = c(3, 5, 2),
  nofollow = c(FALSE, TRUE, FALSE)
)
aggregate_edges(edges)

# Require agreement on nofollow, erroring on a conflict.
try(aggregate_edges(edges, nofollow_policy = "error"))

# Preserve placement features as a list-column for later modeling.
edges_pos <- data.frame(
  from = c("A", "A"),
  to = c("B", "B"),
  position = c(1, 7)
)
aggregate_edges(edges_pos, preserve_cols = "position")

pagerankr documentation built on Oct. 1, 2026, 5:09 p.m.