| Title: | Kinship Analysis with Linked Markers |
|---|---|
| Description: | A 'shiny' application for forensic kinship testing, based on the 'pedsuite' R packages. 'KLINK' is closely aligned with the (non-R) software 'Familias' and 'FamLink', but offers several unique features, including visualisations and automated report generation. The calculation of likelihood ratios supports pairs of linked markers, and all common mutation models. The program is described in Vigeland and Gilfillan (2026) <doi:10.1016/j.fsigen.2026.103578>. |
| Authors: | Magnus Dehli Vigeland [aut, cre] (ORCID: <https://orcid.org/0000-0002-9134-4962>) |
| Maintainer: | Magnus Dehli Vigeland <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.3.1 |
| Built: | 2026-10-13 20:03:40 UTC |
| Source: | https://github.com/magnusdv/klink |
Find, or add, the LR totals in a data frame with marker-wise LR values. The
totals are found by multiplying the values in each column, after removing
NA's.
getTotals(x, cols = c("LRlinked", "LRnolink", "LRnomut")) addTotals(x, cols = c("LRlinked", "LRnolink", "LRnomut"))getTotals(x, cols = c("LRlinked", "LRnolink", "LRnomut")) addTotals(x, cols = c("LRlinked", "LRnolink", "LRnomut"))
x |
A data frame with LR results, typically the output of |
cols |
A vector of column names, by default |
Note that for the multiplication to respect linked markers, the input table
should include LR values for only one marker in each linkage group, and
NA's elsewhere. This is the format used by linkedLR().
getTotals() returns a named numeric. addTotals returns a data
frame equal to the input, but with a row of totals added at the bottom.
res = linkedLR(paternity) getTotals(res) addTotals(res)res = linkedLR(paternity) getTotals(res) addTotals(res)
A list of two pedigrees forming opposing hypotheses about three individuals:
halfsibhalfsib
A list of two ped objects, named H1 and H2.
H1: A and B are full siblings, and C is their half brother
H2: A and B are full siblings, and C is unrelated to them
The individuals are typed with 50 markers, but some genotypes are missing.
library(pedtools) plotPedList(halfsib, hatched = typedMembers) markerSummary(halfsib) linkedLR(halfsib)library(pedtools) plotPedList(halfsib, hatched = typedMembers) markerSummary(halfsib) linkedLR(halfsib)
This launches the KLINK app. runKLINK() is a synonym for launchApp(), but
with an additional argument version.
launchApp() runKLINK(version = NULL)launchApp() runKLINK(version = NULL)
version |
A character, e.g. "1.0.0". If the installed version of KLINK differs from this, the program aborts with an error. |
No return value, called for side effects.
## Not run: launchApp() ## End(Not run)## Not run: launchApp() ## End(Not run)
This function does the main LR calculations of the KLINK app.
linkedLR( pedigrees, linkageMap = map51, linkedPairs = NULL, maxdist = Inf, markerData = NULL, mapfun = "Kosambi", lumpSpecial = TRUE, alleleLimit = 10, verbose = TRUE, debug = FALSE )linkedLR( pedigrees, linkageMap = map51, linkedPairs = NULL, maxdist = Inf, markerData = NULL, mapfun = "Kosambi", lumpSpecial = TRUE, alleleLimit = 10, verbose = TRUE, debug = FALSE )
pedigrees |
A list of two pedigrees. |
linkageMap |
A data frame with columns including |
linkedPairs |
A list of marker pairs. If not supplied, calculated internally with
|
maxdist |
A number, passed onto |
markerData |
A data frame with marker data, typically the output of
|
mapfun |
Name of the map function to be used; either "Haldane" or "Kosambi" (default). |
lumpSpecial |
A logical indicating if special lumping should be activated. This is strongly recommended in all cases with linked STR markers. |
alleleLimit |
A number, by default 10, passed on to |
verbose |
A logical, by default TRUE. |
debug |
A logical, by default FALSE. |
A data frame with detailed LR results.
linkedLR(paternity) # Detailed messages, including reports on lumping linkedLR(paternity, debug = TRUE) # For testing # .linkedLR(paternity, markerpair = c("SE33", "D6S474"))linkedLR(paternity) # Detailed messages, including reports on lumping linkedLR(paternity, debug = TRUE) # For testing # .linkedLR(paternity, markerpair = c("SE33", "D6S474"))
.fam fileLoad .fam file
loadFamFile( path, fallbackModel = "equal", checkLumping = TRUE, withParams = FALSE )loadFamFile( path, fallbackModel = "equal", checkLumping = TRUE, withParams = FALSE )
path |
The path to a |
fallbackModel |
The name of a mutation model; passed on to
|
checkLumping |
A logical. If TRUE (default), and if the pedigree disallows special lumping, unlumpable models are replaced with the fallback model. |
withParams |
A logical indicating if the Familias parameters should be included in
the output. (See |
If withParams = FALSE, a list of two pedigree hypotheses in the form of ped
objects. If withParams = TRUE, a list with components peds, params and hasUnlumpable.
fam = system.file("extdata/halfsib-test.fam", package = "KLINK") peds = loadFamFile(fam) pedtools::plotPedList(peds) loadFamFile(fam, withParams = TRUE)$paramsfam = system.file("extdata/halfsib-test.fam", package = "KLINK") peds = loadFamFile(fam) pedtools::plotPedList(peds) loadFamFile(fam, withParams = TRUE)$params
Functions for loading, subsetting and pairing markers in genetic linkage maps.
loadMap(path) getLinkedPairs(linkageMap = map51, maxdist = Inf) subsetMap(linkageMap, markers)loadMap(path) getLinkedPairs(linkageMap = map51, maxdist = Inf) subsetMap(linkageMap, markers)
path |
Path to a genetic map file, either a tab-separated text file or an Excel
file with extension |
linkageMap |
A data frame with columns |
maxdist |
A positive number indicating the maximum distance (in cM) between paired markers. Markers further apart are considered unlinked. |
markers |
A character vector of marker names to retain. |
loadMap() reads and sorts a genetic map from a text or Excel file, with required
columns Marker, Chr, cM, and optionally a column Mb with physical positions
used in karyograms.
subsetMap() restricts a map to a given set of markers. Marker names are matched
flexibly, ignoring case and the separators "-", ".", "_" and space. The returned map
uses the marker spelling supplied in markers. If multiple map entries match the same
marker, only the first is retained.
getLinkedPairs() identifies disjoint marker pairs from the supplied map. Within each
chromosome, pairs are selected greedily by successively choosing the closest available
markers. Each marker occurs in at most one pair.
loadMap() and subsetMap() return data frames. getLinkedPairs() returns a
list of character vectors, each containing two marker names.
map = norSTR::map51 # Keep only markers present in a pedigree mvec = pedtools::name(sibship[[1]]) map2 = subsetMap(map, mvec) # Subsetting is insensitive to case and separators mvec2 = sub(" ", ".", mvec) |> tolower() subsetMap(map, mvec2) # Pair the remaining markers getLinkedPairs(map2, maxdist = 50)map = norSTR::map51 # Keep only markers present in a pedigree mvec = pedtools::name(sibship[[1]]) map2 = subsetMap(map, mvec) # Subsetting is insensitive to case and separators mvec2 = sub(" ", ".", mvec) |> tolower() subsetMap(map, mvec2) # Pair the remaining markers getLinkedPairs(map2, maxdist = 50)
These objects are re-exported from norSTR::map51 and norSTR::map50.
map51 is the current map, while map50 is retained for reproducibility.
map51 map50map51 map50
Generate table of marker data
markerSummary(pedigrees, replaceNames = FALSE)markerSummary(pedigrees, replaceNames = FALSE)
pedigrees |
A list of 2 pedigrees. |
replaceNames |
A logical, indicating if IDs should be changed to Person1, Person2, ... |
A data frame.
markerSummary(paternity)markerSummary(paternity)
XML file associated with .fam fileParse XML file associated with .fam file
parseXML(xml)parseXML(xml)
xml |
Path to a file with extension |
# (No example included)# (No example included)
A list of two pedigrees forming the hypotheses in a paternity case: H1 (AF
is the father of CH) and H2 (unrelated). AF and CH are genotyped with
11 markers, with allele frequencies from norSTR::norwayDB.
paternitypaternity
A list of two pedigrees, named H1 and H2.
pedtools::plotPedList(paternity, marker = "SE33") markerSummary(paternity) forrel::kinshipLR(paternity)pedtools::plotPedList(paternity, marker = "SE33") markerSummary(paternity) forrel::kinshipLR(paternity)
A list of two pedigrees forming opposing hypotheses about two individuals
NN1 and NN2: FS (full siblings) vs. HS (half siblings). Both
individuals are genotyped with the 23 markers included in the Fusion 6C kit.
Among the 23 markers, four pairs are linked:
sibshipsibship
A list of two ped objects, named FS and HS.
TPOX and D2S441 (86.0 cM, 9 & 13 alleles)
D5S818 and CSF1PO (26.2 cM, 9 & 11 alleles)
vWA and D12S391 (11.4 cM, 12 & 23 alleles)
D21S11 and Penta D (45.7 cM, 26 & 24 alleles)
(Genetic distances taken from the norSTR::map51 linkage map.)
library(pedtools) plotPedList(sibship, hatched = typedMembers) markerSummary(sibship) linkedLR(sibship)library(pedtools) plotPedList(sibship, hatched = typedMembers) markerSummary(sibship) linkedLR(sibship)
This function produces an Excel document containing the genotype data and various LR tables.
writeResult( resultTable, pedigrees, linkageMap, markerData, outfile, notes = NULL, famname = NULL, hideEmpty = FALSE, settings = NULL, XML = NULL )writeResult( resultTable, pedigrees, linkageMap, markerData, outfile, notes = NULL, famname = NULL, hideEmpty = FALSE, settings = NULL, XML = NULL )
resultTable |
A data frame. |
pedigrees |
A list of two |
linkageMap |
A data frame. |
markerData |
A data frame. |
outfile |
The output file name. |
notes |
A character vector. |
famname |
The name of the input |
hideEmpty |
A logical, indicating if untyped markers should be dropped. |
settings |
A list of KLINK settings to be included in the output |
XML |
Optional data from .xml file. |
# Built-in dataset `paternity` peds = paternity map = norSTR::map51 mdata = markerSummary(peds) # Result table LRtab = linkedLR(pedigrees = peds, linkageMap = map, markerData = mdata, verbose = FALSE) # Write to excel tmp = paste0(tempfile(), ".xlsx") writeResult(LRtab, pedigrees = peds, linkageMap = map, markerData = mdata, outfile = tmp) # openxlsx::openXL(tmp)# Built-in dataset `paternity` peds = paternity map = norSTR::map51 mdata = markerSummary(peds) # Result table LRtab = linkedLR(pedigrees = peds, linkageMap = map, markerData = mdata, verbose = FALSE) # Write to excel tmp = paste0(tempfile(), ".xlsx") writeResult(LRtab, pedigrees = peds, linkageMap = map, markerData = mdata, outfile = tmp) # openxlsx::openXL(tmp)