Skip to contents

This function extracts IBD segments between pairs of individuals or nodes from a given tree sequence.

Usage

ts_ibd(
  ts,
  within = NULL,
  between = NULL,
  maximum_time = NULL,
  minimum_length = 0,
  sf = TRUE
)

Arguments

ts

Tree sequence object of the class slendr_ts

within

A character vector with individual names or an integer vector with node IDs indicating a set of nodes within which to look for IBD segments.

between

A list of lists of character vectors with individual names or integer vectors with node IDs, indicating a set of nodes between which to look for shared IBD segments.

maximum_time

Oldest MRCA of a node to be considered as an IBD ancestor to return that IBD segment in results. This is useful for reducing the total amount of IBD returned.

minimum_length

Minimum length of a ("squashed") IBD segment for it to be included in the results

sf

If IBD segments in a spatial tree sequence are being analyzed, should the returned table be a spatial sf object? Default is TRUE.

Value

A data frame with IBD coordinates of each IBD segment shared by any pair of nodes in the tree sequence

Details

The interface of this function is highly experimental. For full control over IBD segment detection in tree-sequence data, users can (and perhaps, for the time being, should) directly use the underlying tskit method ibd_segments (see https://tskit.dev/tskit/docs/stable/python-api.html#tskit.TreeSequence.ibd_segments).

Internally, this function leverages the tskit TreeSequence method ibd_segments. However, note that the ts_ibd function always returns a data frame of IBD tracts, it does not provide an option to iterate over individual IBD segments as shown in the official tskit documentation at https://tskit.dev/tskit/docs/stable/ibd.html. In general, R handles heavy iteration rather poorly and, as a result, this function does not attempt to serve as a full wrapper to ibd_segments.

Unfortunately, the distinction between "squashed IBD" (what many would consider to be the expected definition of IBD) and tskit’s IBD which is defined via distinct genealogical paths (see https://github.com/tskit-dev/tskit/issues/2459 for a discussion of the topic), makes the meaning of the filtering parameter of the ibd_segments() method of tskit minimum_length somewhat unintuitive. As of this moment, the minimum length argument filters on IBD segments on the "squashed" level, not the level of smaller individual IBD segments which the tskit machinery operates with. Again, for more details, refer to the resources linked above.

See also

ts_extend for information about the "extend haplotypes" procedure

Examples

init_env()
#> Python virtual environment for slendr has been activated.

# load an example model with an already simulated tree sequence
slendr_ts <- system.file("extdata/models/introgression_slim.trees", package = "slendr")
model <- read_model(path = system.file("extdata/models/introgression", package = "slendr"))

# load the tree-sequence object from disk
ts <- ts_read(slendr_ts, model)

# find IBD segments between specified Neanderthals and Europeans
ts_ibd(
  ts,
  between = list(c("NEA_1", "NEA_2"), c("EUR_1", "EUR_2")),
  minimum_length = 40000
)
#> # A tibble: 28 × 13
#>    node1 node2 length  mrca node1_time node2_time tmrca   left  right name1
#>    <int> <int>  <dbl> <dbl>      <dbl>      <dbl> <dbl>  <dbl>  <dbl> <chr>
#>  1     0    16 500000    84      70000          0 20040      0 500000 NEA_1
#>  2     0    17 500000    84      70000          0 20040      0 500000 NEA_1
#>  3     0    18 207423    84      70000          0 20040      0 207423 NEA_1
#>  4     0    18 165650    81      70000          0  2371 207423 373073 NEA_1
#>  5     0    18  81649    81      70000          0  2371 382630 464279 NEA_1
#>  6     0    18  35721    84      70000          0 20040 464279 500000 NEA_1
#>  7     0    19 500000    84      70000          0 20040      0 500000 NEA_1
#>  8     1    16 500000    84      70000          0 20040      0 500000 NEA_1
#>  9     1    17 500000    84      70000          0 20040      0 500000 NEA_1
#> 10     1    18 207423    84      70000          0 20040      0 207423 NEA_1
#> # ℹ 18 more rows
#> # ℹ 3 more variables: name2 <chr>, pop1 <fct>, pop2 <fct>