TrustRank (Gyöngyi, Garcia-Molina & Pedersen, 2004) is personalized PageRank whose teleport vector is concentrated on a set of **trusted seed** pages instead of being uniform. Trust then flows outward along links and attenuates with distance (the PageRank damping factor *is* the trust-attenuation mechanism), so pages well-linked from the trusted core score high and pages far from it score low.
`pagerankr` implements this with **no new solver**: a trusted-seed prior is exactly a `prior_df` for the existing TIPR personalization path. [trust_seed_prior()] builds that prior from a seed set, and [trustrank()] is the worked convenience wrapper that builds the seed prior and runs [pagerank()] with it.
This is **seed-biased PageRank**, not a full spam-detection system: it reproduces the biased-propagation core of TrustRank, leaving seed selection (expert-reviewed "good" pages) to the caller.
Usage
trust_seed_prior(
trusted_seeds,
seed_weight = NULL,
seed_url_col = "url",
seed_weight_col = "weight"
)
trustrank(
edge_list_df,
trusted_seeds,
seed_weight = NULL,
seed_url_col = "url",
seed_weight_col = "weight",
...
)Arguments
- trusted_seeds
The trusted seed set. Either a character vector of trusted URLs (each gets equal seed weight unless `seed_weight` is given), or a data frame with a URL column and a numeric weight column (see `seed_url_col` / `seed_weight_col`) for unequal trust.
- seed_weight
Optional numeric trust weight for a character-vector `trusted_seeds`: either one value per seed or a single value recycled to all seeds. Ignored when `trusted_seeds` is a data frame. Default `NULL` (every seed weight `1`, i.e. a uniform distribution over the trusted set, as in the original TrustRank).
- seed_url_col, seed_weight_col
Column names used when `trusted_seeds` is a data frame. Defaults `"url"` / `"weight"`. Ignored for a character vector.
- edge_list_df
A data frame representing the edge list, typically with columns like "from" and "to".
- ...
Additional arguments forwarded to [pagerank()] (e.g. `redirects_df`, `rurl_params`, `prior_transform`, `prior_alpha`, `damping`). Passing `prior_df`, `prior_url_col`, or `prior_weight_col` is an error.
Value
[trust_seed_prior()] returns a data frame with `url` and `weight` columns, suitable as the `prior_df` argument to [pagerank()].
[trustrank()] returns the [pagerank()] result data frame (`node_name`, `pagerank`, and the `prior_weight` column the prior path adds), carrying the usual `"transition_audit"` attribute.
Details
The seed weights are an **additive trust budget**: when two seed URLs fold onto the same vertex (redirect/canonical variants) their weights sum, exactly as the [pagerank()] / [align_prior_to_vertices()] prior contract specifies. Equal weights reproduce TrustRank's uniform seed distribution; unequal weights express graded trust.
[trustrank()] forwards `...` to [pagerank()], so the full graph-preparation surface (redirects, canonicals, URL cleaning, domain/host filtering, edge weights, duplicate-edge policy) and the prior-shaping knobs (`prior_transform`, `prior_alpha`) are all available. In particular `prior_alpha` mixes a uniform teleport baseline back in: `prior_alpha = 0` (the default) is pure trust teleport (untrusted, unreachable pages get no teleport mass), while a small positive value gives every page a floor. Because this owns the prior, passing `prior_df`, `prior_url_col`, or `prior_weight_col` to [trustrank()] is an error — supply `trusted_seeds`.
Examples
edges <- data.frame(
from = c("/", "/", "/hub", "/hub", "/spam", "/good"),
to = c("/hub", "/good", "/good", "/deep", "/good", "/hub")
)
# Build a trusted-seed prior, then run it through pagerank() manually.
prior <- trust_seed_prior(c("/", "/hub"))
pr <- pagerank(edges, prior_df = prior, clean_edge_urls = FALSE)
#> TIPR prior aligned: 2/5 real vertices carry authority; transform='none', alpha=0 (uniform mass ~0.0%). 0 prior URL(s) (sum weight 0) did not fold onto any vertex and were dropped.
# ...or in one call with the convenience wrapper.
tr <- trustrank(edges, c("/", "/hub"), clean_edge_urls = FALSE)
#> TIPR prior aligned: 2/5 real vertices carry authority; transform='none', alpha=0 (uniform mass ~0.0%). 0 prior URL(s) (sum weight 0) did not fold onto any vertex and were dropped.
print(tr)
#> node_name pagerank prior_weight
#> 1 / 0.1515500 0.5
#> 2 /deep 0.1801176 0.0
#> 3 /good 0.2445263 0.0
#> 4 /hub 0.4238061 0.5
#> 5 /spam 0.0000000 0.0