Skip to contents
0.16.6 documentation

Complete canonical API text; task articles explain the workflows. Tutorials

Site guide · find your task

Connects feature intervals belonging to the same declared cluster for explicitly requested sequence pairs. Membership is an input assertion, not an inferred alignment: no identity, alignment length or score is invented. Both sequence and feature identifiers are kept exactly as supplied.

Usage

Code
link_ggchord_clusters(
  feature_data,
  membership,
  pairs,
  paralogs = c("drop", "all"),
  segment_policy = c("error", "span"),
  max_links = 10000
)

Arguments

feature_data

Feature data frame with feature_id, accver, start, end, and optional strand, accepted by as_ggchord_feature().

membership

Data frame with feature_id and cluster_id. A feature can belong to one cluster; extra columns are retained in the report.

pairs

Data frame with explicit qaccver and saccver comparisons.

paralogs

How to handle multiple members per cluster and sequence: "drop" (default) or explicit "all".

segment_policy

"error" (default) rejects repeated feature IDs; "span" explicitly uses a validated discontinuous feature's outer bounds.

Positive integer upper limit for generated rows, default 10000. Exceeding it stops before Cartesian products are allocated.

Value

A list with data, an ordinary link data frame, and report. Links retain cluster/member IDs, strands, source feature/membership rows and segment tables. report$comparisons lists member counts, output counts and retention/omission reasons for each requested pair and clusters represented on either side (clusters absent from both sides are omitted); report$members retains membership metadata with resolution status. report$valid is false when membership contains unknown feature IDs.

Details

The default paralogs = "drop" retains only comparisons containing exactly one member on each side. Ambiguous one-to-many/many-to-many comparisons are omitted and reported. "all" explicitly requests their Cartesian product. Its total size is checked against max_links before any links are expanded. Pair row order and its query/subject roles are retained. Self-pairs and repeated pairs (including the reversed pair) must be resolved by the caller.

Feature IDs normally identify one row. If repeated rows deliberately describe one discontinuous feature, segment_policy = "span" requires one sequence, one strand, and non-overlapping intervals. The link then anchors the feature's outer genomic bounds; real segments remain in the qsegments and ssegments list-columns. This span is a feature anchor, never an exon-to-exon alignment, and does not remove intervening sequence. Nested segments fields in a single feature row are retained unchanged.

Unknown feature IDs in membership are reported and omitted. Malformed identifiers, conflicting cluster assignments, ambiguous repeated features, unsupported origin-crossing intervals and unknown pair sequence IDs stop with an actionable error. Feature IDs not assigned to a cluster are also listed in the report. Negative strands reverse their link endpoints; unknown strands retain increasing coordinates and orientation_known = FALSE.

Examples

Code
library(ggchord)
library(dplyr)
data(plasmid_example_pUC19)
data(plasmid_example_pETDuet_1)
homolog_source <- bind_rows(plasmid_example_pUC19, plasmid_example_pETDuet_1)
homolog_seq <- homolog_source |>
  select(accver, length)
cluster_features <- homolog_source |>
  find_common_features() |>
  filter(type == "CDS", anno == "AmpR") |>
  select(accver, start, end, strand, anno) |>
  arrange(match(accver, homolog_source$accver)) |>
  mutate(feature_id = paste(accver, start, end, sep = ":"))
# Membership is computed from exact strand-corrected CDS DNA equality, not gene names.
reverse_complement <- function(sequence) {
  bases <- strsplit(sequence, "")[[1]]
  chartr("ACGT", "TGCA", paste(rev(bases), collapse = ""))
}
coding_sequences <- cluster_features |>
  left_join(select(homolog_source, accver, sequence), by = "accver") |>
  rowwise() |>
  mutate(
    coding_dna = substr(sequence, start, end),
    coding_dna = if (strand == "-") reverse_complement(coding_dna) else coding_dna
  ) |>
  ungroup()
cds_dna <- pull(coding_sequences, coding_dna)
membership <- tibble(
  feature_id = cluster_features$feature_id,
  cluster_id = paste0("exact_CDS_", match(cds_dna, unique(cds_dna)))
)
homologs <- link_ggchord_clusters(cluster_features, membership,
  pairs = tibble(qaccver = homolog_seq$accver[1], saccver = homolog_seq$accver[2])
)
loci <- find_ggchord_loci(homolog_seq, cluster_features,
  targets = cluster_features$feature_id[cluster_features$anno == "AmpR"][1], upstream = 100, downstream = 100
)
gene_palette <- c("+" = "#56887C", "-" = "#B58169", "." = "#AAB9AE")
doc_theme <- theme_ggchord_publication(
  axis.text = element_text(size = 9), axis.text.check.overlap = TRUE
) +
  theme(legend.position = "bottom")
p_homologs <- ggchord(seq_data = homolog_seq) +
  geom_link_ribbon(data = homologs$data, fill = "#ADC5B9", alpha = .6) +
  geom_seq() +
  geom_gene(data = cluster_features) +
  geom_seq_label(size = 4) +
  coord_collinear() +
  scale_gene_fill_manual(values = gene_palette) +
  doc_theme