| hits | R Documentation |
Computes Kleinberg's HITS hub and authority scores over the same cleaned, redirect/canonical-folded, domain-filtered, deduplicated link graph that [pagerank()] builds, so node identities line up across the two centrality measures. Wraps 'igraph::hits_scores()' (the non-deprecated successor of 'igraph::hub_score()' / 'igraph::authority_score()').
hits(
edge_list_df,
redirects_df = NULL,
clean_edge_urls = TRUE,
clean_redirect_urls = TRUE,
rurl_params = list(),
self_loops = c("drop", "keep"),
drop_isolates_flag = TRUE,
weight_col = NULL,
duplicate_edge_policy = c("collapse", "aggregate", "count_instances"),
edge_from_col = "from",
edge_to_col = "to",
redirect_from_col = "from",
redirect_to_col = "to",
duplicate_from_policy = c("strict", "first_wins", "last_wins", "most_frequent",
"prune_source", "resolve_if_consistent"),
loop_handling = c("error", "prune_loop", "break_arrow"),
canonicals_df = NULL,
canonical_from_col = "from",
canonical_to_col = "to",
clean_canonical_urls = TRUE,
canonical_duplicate_from_policy = c("strict", "first_wins", "last_wins",
"most_frequent", "prune_source", "resolve_if_consistent"),
canonical_loop_handling = c("error", "prune_loop", "break_arrow"),
canonical_conflict_policy = c("redirect_wins", "error", "canonical_wins"),
keep_domains = NULL,
exclude_domains = NULL,
keep_hosts = NULL,
exclude_hosts = NULL,
scale = TRUE,
...
)
edge_list_df |
A data frame representing the edge list, typically with columns like "from" and "to". Edges are expected to be page-to-page hyperlinks: 'pagerank()' is graph-agnostic and treats every endpoint as a node, so resource links (images, CSS, JS, and other non-HTML references) must be filtered upstream or they collect authority as ordinary vertices. 'pagerank_screaming_frog()' does this at the crawl boundary via [sf_graph_eligible()] ('Hyperlink' only); a hand-built or non-SF edge list should apply the same hyperlink-only filter before scoring. |
redirects_df |
An optional data frame for redirect rules, typically with "from" and "to" columns. Defaults to NULL. |
clean_edge_urls |
Logical, whether to clean URLs in the edge list. Defaults to TRUE. |
clean_redirect_urls |
Logical, whether to clean URLs in the redirect list. Defaults to TRUE. Only effective if 'redirects_df' is provided. |
rurl_params |
A list of parameters to pass to 'rurl::clean_url'. Defaults to an empty list. 'protocol_handling' defaults to '"keep"' and 'case_handling' to '"lower_host"' for cross-project canonicalization consistency. If you set 'host_encoding' ('"idna"' or '"unicode"') to fold internationalized (IDN) hosts, that same value is also passed to the domain-filtering step so its comparisons stay consistent with the cleaned node keys. (Registrable-domain matching is encoding-independent, so this only matters if host-level filtering is involved.) |
self_loops |
A character string specifying how to handle self-loops. Either "drop" (default) or "keep". |
drop_isolates_flag |
Logical, whether to drop isolated nodes before PageRank computation. Defaults to TRUE. |
weight_col |
Optional name of a numeric column in 'edge_list_df' containing edge weights. Higher weights make edges more likely to be followed. If 'NULL' (default), all edges have equal weight. |
duplicate_edge_policy |
How repeated 'from -> to' rows are represented after URL cleaning, redirect/canonical folding, and domain filtering. One of:
|
edge_from_col, edge_to_col |
Names of from/to columns in 'edge_list_df'. |
redirect_from_col, redirect_to_col |
Names of from/to columns in 'redirects_df'. |
duplicate_from_policy |
How to handle conflicting redirects in 'redirects_df'. Passed through to [resolve_redirects()]. Default '"strict"' (error on conflicts). See [resolve_redirects()] for all available policies. |
loop_handling |
How to handle redirect cycles. Passed through to [resolve_redirects()]. Default '"error"'. See [resolve_redirects()] for all available policies. |
canonicals_df |
An optional data frame of declared 'rel=canonical' links, with 'from'/'to' columns (or as set by 'canonical_from_col' / 'canonical_to_col') pairing a source URL with the canonical it declares. Default 'NULL' (opt-in; the default preserves current behavior). Canonicals are a **distinct, advisory** signal from enforced 3xx 'redirects_df': they are tracked separately and audited via [audit_canonicals()] / [audit_fold()], then folded into the same composed map as redirects (see [build_fold_map()]). Self-canonicals drop as no-ops. |
canonical_from_col, canonical_to_col |
From/to columns in 'canonicals_df'. Default '"from"' / '"to"'. |
clean_canonical_urls |
Logical, whether to clean URLs in 'canonicals_df' using the same resolved 'rurl_params' profile as edge and redirect cleaning. Default 'TRUE'. Only effective when 'canonicals_df' is provided. |
canonical_duplicate_from_policy |
How to handle a canonical source that declares multiple distinct canonicals. Reuses the 'duplicate_from_policy' enum (see [resolve_redirects()]). Default '"strict"'. |
canonical_loop_handling |
How to handle cycles among declared canonicals. Reuses the 'loop_handling' enum. Default '"error"'. |
canonical_conflict_policy |
How to resolve a redirect-vs-canonical disagreement on the **same source** URL. One of '"redirect_wins"' (default; the 3xx wins and the canonical on a redirecting source is ignored and flagged), '"error"' (error on genuine disagreement), or '"canonical_wins"' (the declared canonical wins for that source, still flagged). See [build_fold_map()]. |
keep_domains |
Optional character vector of domains to keep. When provided, edges are filtered via [filter_links_by_domain()] so that only links where both endpoints belong to one of the specified domains are included. Useful for restricting to internal links. Default 'NULL' (no domain filtering). **Ordering:** filtering runs *after* redirect/canonical folding, so it scopes the post-fold (canonical) namespace, not the crawled input. If an out-of-scope canonical/redirect rewrites the crawled domain onto a different one, filtering on the crawled domain matches nothing (an empty graph). To scope the INPUT you crawled, run [filter_links_by_domain()] on the edge list *before* calling 'pagerank()'. |
exclude_domains |
Optional character vector of domains to exclude. Edges where either endpoint belongs to one of these domains are removed. Like 'keep_domains', this filters the post-fold namespace (see the ordering note above). Default 'NULL' (no exclusion). |
keep_hosts |
Optional character vector of exact hosts to keep (e.g. '"www.example.com"'), as opposed to registrable domains. Matched on the exact host using the same canonicalization profile as cleaning, so IDN folding ('host_encoding' in 'rurl_params') applies consistently. Default 'NULL'. |
exclude_hosts |
Optional character vector of exact hosts to exclude. Edges where either endpoint matches one of these hosts are removed. Ignore rules override keep rules. Default 'NULL'. |
scale |
Logical, passed to 'igraph::hits_scores()' via [compute_hits()]. 'TRUE' (default) scales each score so its maximum is '1'; 'FALSE' returns the unit-norm eigenvectors. See [compute_hits()]. |
... |
Additional arguments forwarded to [compute_hits()] and then to 'igraph::hits_scores()'. |
## Relationship to the PageRank pipeline
'hits()' reuses the exact identity-forming steps of [pagerank()] — URL canonicalization (the same resolved 'rurl' profile), the same composed redirect + canonical fold map, the same domain/host filtering, the same 'duplicate_edge_policy' deduplication, and the same self-loop / isolate handling. The resulting vertex set therefore matches 'pagerank()' run with the same arguments, so hub, authority, and PageRank can be joined on 'node_name' without re-canonicalizing.
The PageRank-specific, *forward-flow* modeling devices have **no HITS analog and are intentionally not exposed**: nofollow evaporation, the indexability (noindex / robots.txt) transforms, the TIPR teleport prior, and the 'reverse' flag. HITS already computes both directions of authority flow (hub is the outflow-oriented score, authority the inflow-oriented one), so a separate reversal is unnecessary.
## Matrix formulation and the whole-graph caveat
With adjacency matrix A, **authority** is the dominant eigenvector of
A^\top A ("pages pointed to by pages that point to many things") and
**hub** is the dominant eigenvector of A A^\top ("pages that point to
pages pointed to by many things"). See [compute_hits()].
Kleinberg's original HITS (1999) was run on a small, **query-focused base set** of pages, where the hub/authority distinction is sharply interpretable. 'hits()' instead runs on the **full (or user-filtered) site graph** that 'pagerankr' assembles. The eigenvector computation is identical and correct, but the interpretation shifts: scores describe hub/authority structure across the whole crawled graph rather than relevance to a specific query. Treat them as site-wide structural centralities, not query-relevance scores.
A data frame with one row per node and columns 'node_name', 'hub', and 'authority' (column names configurable via '...'). Hub and authority are scaled to a maximum of '1' by default ('scale = TRUE').
[compute_hits()] for the computational core, [pagerank()] for the PageRank analog sharing this identity pipeline.
edges <- data.frame(
from = c("http://A.com/", "http://A.com/", "B.com"),
to = c("B.com", "C.com", "C.com")
)
hits(edges)
# Hub vs authority: a pure outflow page tops hub, a pure inflow page tops
# authority.
h <- hits(edges)
h[which.max(h$hub), ]
h[which.max(h$authority), ]
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.