| Title: | Assortative Mating Simulation and Multivariate Bernoulli Variates |
|---|---|
| Description: | Simulation of phenotype / genotype data under assortative and disassortative mating. Includes functions for generating Bahadur order-2 multivariate Bernoulli variables with general and diagonal-plus-low-rank correlation structures, and for writing simulated genotypes to disk as binary int8 or PLINK bed files. Further details are provided in: Border and Malik (2023) <doi:10.1186/s12859-023-05442-6>. |
| Authors: | Richard Border [aut, cre] (ORCID: <https://orcid.org/0000-0002-6293-2968>), Osman Malik [aut] (ORCID: <https://orcid.org/0000-0003-4477-481X>) |
| Maintainer: | Richard Border <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.1.0 |
| Built: | 2026-07-23 15:56:27 UTC |
| Source: | https://github.com/cran/rBahadur |
Compute Diagonal plus Low Rank equilibrium covariance structure
am_covariance_structure(beta, AF, r)am_covariance_structure(beta, AF, r)
beta |
vector of standardized diploid allele-substitution effects |
AF |
vector of allele frequencies |
r |
cross-mate phenotypic correlation, in the open interval (-1, 1). Negative values correspond to disassortative mating. |
For r > 0 the low-rank term is added and attr(U, "sign") is 1.
For r < 0 it is subtracted and the attribute is -1, because a positive
semidefinite rank-one term can only increase genetic variance whereas
disassortative mating reduces it. The returned vector in that case is the
analytic continuation of the positive branch, which is purely imaginary.
For r = 0 the vector is zero, since panmixia induces no disequilibrium.
Vector 'U' such that corresponds to the expected
haploid LD-matrix given the specified genetic architecture (encoded by 'beta'
and 'AF') and cross-mate phenotypic correlation 'r', where the sign
is attr(U, "sign"). It is assumed that the total phenotypic
variance at generation zero is one.
The returned vector carries attr(U, "sign"), which records whether the
rank-one term is added or subtracted. Subsetting or coercing the vector,
including with as.vector(), c(), or U[i], drops that
attribute. Because rb_dplr() falls back to sign = 1 when the attribute
is absent, this silently turns a disassortative structure into an
assortative one, with no error at any point. If you manipulate U before
passing it to rb_dplr(), pass sign = -1 explicitly for r < 0
rather than relying on the attribute to survive.
Disassortative mating leaves the Bahadur order-2 feasible region sooner
than assortative mating does. The returned vector can satisfy the
discriminant condition checked here and still drive rb_dplr() outside
[0, 1] during sampling, because feasibility there is a property of the
realized draws rather than of the parameters alone. Infeasibility becomes
more likely as n grows, since it only takes one individual to fall
outside the region. Positive r was feasible in every configuration
tested. Negative r was not: at h2_0 = 0.5 and 1500 causal variants,
r = -0.3 sampled reliably at 4000 individuals, while r = -0.4 sampled
reliably at 2000 individuals but failed for some seeds at 4000. Raising
min_MAF widens the envelope. If rb_dplr() reports infeasible
probabilities, reduce the magnitude of r, raise min_MAF, or increase
the number of causal variants.
set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5; min_MAF=.1 betas <- rnorm(m,0,sqrt(h2_0/m)) afs <- runif(m, min_MAF, 1-min_MAF) output <- am_covariance_structure(betas, afs, r)set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5; min_MAF=.1 betas <- rnorm(m,0,sqrt(h2_0/m)) afs <- runif(m, min_MAF, 1-min_MAF) output <- am_covariance_structure(betas, afs, r)
Compute heritability ('h2_eq'), genetic variance ('vg_0'), and cross-mate genetic correlation ('rg_eq') at equilibrium under univariate primary-phenotypic assortative mating. These equations can be derived from Nagylaki's results (see below) under the assumption that number of causal variants is large (i.e., taking the limit as the number of causal variants approaches infinity).
h2_eq(r, h2_0) rg_eq(r, h2_0) vg_eq(r, vg_0, h2_0)h2_eq(r, h2_0) rg_eq(r, h2_0) vg_eq(r, vg_0, h2_0)
r |
cross-mate phenotypic correlation, with values in |
h2_0 |
generation zero (panmictic) heritability, with values in
|
vg_0 |
non-negative generation zero (panmictic) additive genetic variance component |
A single numerical quantity representing the equilibrium heritability (h2_eq),
the equilibrium cross-mate genetic correlation (rg_eq), or the equilibrium genetic
variance (vg_eq).
Nagylaki, T. Assortative mating for a quantitative character. J. Math. Biology 16, 57–74 (1982). https://doi.org/10.1007/BF00275161
set.seed(1) vg_0= .6; h2_0 = .5; r =.5 h2_eq(r, h2_0) rg_eq(r, h2_0) vg_eq(r, vg_0, h2_0)set.seed(1) vg_0= .6; h2_0 = .5; r =.5 h2_eq(r, h2_0) rg_eq(r, h2_0) vg_eq(r, vg_0, h2_0)
Combines the global linkage disequilibrium induced by assortative mating
with the local linkage disequilibrium induced by limited recombination.
Causal variants are drawn with rb_dplr(), giving the dense genome-wide
structure assortative mating produces, and the remaining markers are filled
in by copying contiguous haplotype blocks from a reference panel, giving
realistic short-range structure. Block boundaries are sampled from the
panel's genetic map, so breakpoints concentrate where recombination is high.
am_mosaic( h2_0, r, n, panel, causal_idx = NULL, m = NULL, path = NULL, format = c("individual", "variant", "bed"), batch_size = NULL )am_mosaic( h2_0, r, n, panel, causal_idx = NULL, m = NULL, path = NULL, format = c("individual", "variant", "bed"), batch_size = NULL )
h2_0 |
generation zero (panmictic) heritability, in |
r |
cross-mate phenotypic correlation, in the open interval (-1, 1). Negative values give disassortative mating. |
n |
positive whole-number count of individuals to simulate |
panel |
reference panel: a list with |
causal_idx |
integer indices of the markers to treat as causal. If
|
m |
whole-number count of causal variants, used only when |
path, format, batch_size
|
streaming options, exactly as in
|
Genotypes at the causal loci are exactly what rb_dplr() drew, so
the equilibrium relationships in h2_eq() and vg_eq() hold there, while
surrounding markers inherit the panel's correlation structure. Combining
the two rather than approximating them jointly sidesteps the feasibility
limit in am_covariance_structure(): representing strong local LD and
genome-wide assortative mating in a single Bahadur order-2 distribution is
generally not possible.
The equilibrium formulas are large-locus results. Calls with fewer than 50
causal variants are allowed but warn because realized variances can differ
materially from the targets. Set
options(rBahadur.warn_small_m = FALSE) to silence this warning after
deciding that the finite-locus approximation is appropriate.
Each block is copied from one panel haplotype, so within a block the simulated data reproduces panel LD exactly, while correlation across a breakpoint is broken apart from what the causal variants carry. More causal variants therefore means more, shorter blocks.
Because the panel is finite, the simulated data cannot contain haplotypes the panel does not, and a small panel will show inflated identity by descent between simulated individuals.
A list with y, g, AF (allele frequencies at the causal loci),
beta_std, beta_raw, causal_idx, and pos. With path = NULL it also
carries X, an n by p integer matrix of diploid genotypes at every
panel marker. With path supplied, X is omitted and path, format,
n, m, h2_0, and r are added, where m counts all panel markers
written rather than only the causal ones.
am_simulate() for the unlinked-loci case, and kg_reference()
for the bundled 1000 Genomes panel.
panel <- kg_reference() sim <- am_mosaic(h2_0 = 0.5, r = 0.4, n = 50, panel = panel, m = 50) dim(sim$X) ## neighbouring markers are correlated because they are copied together, ## which is the local LD that am_simulate() cannot produce j <- sim$causal_idx[10] cor(sim$X[, j], sim$X[, j + 1])panel <- kg_reference() sim <- am_mosaic(h2_0 = 0.5, r = 0.4, n = 50, panel = panel, m = 50) dim(sim$X) ## neighbouring markers are correlated because they are copied together, ## which is the local LD that am_simulate() cannot produce j <- sim$causal_idx[10] cor(sim$X[, j], sim$X[, j + 1])
Simulate genotype/phenotype data under equilibrium univariate AM.
am_simulate( h2_0, r, m, n, afs = NULL, min_MAF = 0.1, haplotypes = FALSE, path = NULL, format = c("individual", "variant", "bed"), batch_size = NULL )am_simulate( h2_0, r, m, n, afs = NULL, min_MAF = 0.1, haplotypes = FALSE, path = NULL, format = c("individual", "variant", "bed"), batch_size = NULL )
h2_0 |
generation zero (panmictic) heritability, in |
r |
cross-mate phenotypic correlation, in the open interval (-1, 1). Negative values correspond to disassortative mating. |
m |
number of biallelic causal variants; a whole number of at least 2 |
n |
positive whole-number sample size |
afs |
(optional). Allele frequencies to use. If not provided, |
min_MAF |
(optional) minimum minor allele frequency for causal variants.
Ignored if if |
haplotypes |
logical. If TRUE, includes (phased) haploid genotypes in output. Defaults to FALSE |
path |
(optional) file prefix. If supplied, genotypes are streamed to
disk in batches rather than returned in memory, and |
format |
on-disk layout when |
batch_size |
(optional) number of individuals per batch for
|
The "variant" and "bed" layouts stream over loci and reproduce
the in-memory genotypes exactly under a given seed at any batch_size. The
"individual" layout streams over people and matches only when
batch_size >= n, because a batch of rows is not contiguous in R's
column-major random draw. haplotypes = TRUE cannot be combined with
path.
The equilibrium formulas are large-locus results. Calls with fewer than 50
causal variants are allowed but warn because realized variances can differ
materially from the targets, especially when m is very small. Set
options(rBahadur.warn_small_m = FALSE) to silence this warning after
deciding that the finite-locus approximation is appropriate.
A list. Without path it contains y, g, X, AF, beta_std,
beta_raw, and H when haplotypes is TRUE. With path it is returned
invisibly, omits X, and adds path, format, n, m, h2_0, r, and
min_MAF; these are also saved in <path>.rds as the call's provenance
record.
set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5 ## simulate genotype/phenotype data sim_dat <- am_simulate(h2_0, r, m, n) str(sim_dat) ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(sim_dat$g)/var(sim_dat$y)) h2_eq(r, h2_0) ## stream genotypes to disk instead of holding them in memory p <- file.path(tempdir(), "am_sim") meta <- am_simulate(h2_0, r, m, n, path = p, format = "variant") dim(read_genotypes(p)) ## disassortative mating neg <- am_simulate(h2_0, -0.3, m, n) var(neg$g) < var(sim_dat$g)set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5 ## simulate genotype/phenotype data sim_dat <- am_simulate(h2_0, r, m, n) str(sim_dat) ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(sim_dat$g)/var(sim_dat$y)) h2_eq(r, h2_0) ## stream genotypes to disk instead of holding them in memory p <- file.path(tempdir(), "am_sim") meta <- am_simulate(h2_0, r, m, n, path = p, format = "variant") dim(read_genotypes(p)) ## disassortative mating neg <- am_simulate(h2_0, -0.3, m, n) var(neg$g) < var(sim_dat$g)
Convenience wrapper that fetches a window of phased 1000 Genomes data along
with a genetic map and hands both to vcf_to_panel(). It exists so the
vignette's workflow can be reproduced at realistic scale; it requires
network access and downloads a large file, so it is not run in examples or
tests.
download_1kg_panel( chrom = "22", start = 2e+07, end = 2.1e+07, dest = tempdir(), ... )download_1kg_panel( chrom = "22", start = 2e+07, end = 2.1e+07, dest = tempdir(), ... )
chrom |
autosome, as a string from |
start, end
|
base pair bounds of the region to keep |
dest |
directory in which to cache downloads. Defaults to a temporary directory. |
... |
further arguments passed to |
Streams the VCF and stops reading once end is passed, so a small
window costs far less than the whole chromosome. The data are the GRCh38
phased biallelic release, and the genetic map is the GRCh38 PLINK map
distributed with BEAGLE. A new cache file is published only after the
stream reaches a variant beyond end, preventing an interrupted download
from being reused as a complete region.
A panel list suitable for am_mosaic().
## requires network access if (interactive()) { panel <- download_1kg_panel("22", 20e6, 20.5e6, max_samples = 200) dim(panel$haplotypes) }## requires network access if (interactive()) { panel <- download_1kg_panel("22", 20e6, 20.5e6, max_samples = 200) dim(panel$haplotypes) }
A small real reference panel, included so that examples, tests, and the
vignette run offline. It covers a 1 Mb window of chromosome 22 and is
intended for demonstration rather than analysis; use vcf_to_panel() or
download_1kg_panel() to build a panel at realistic scale.
kg_reference()kg_reference()
A list with haplotypes (520 by 2500 raw matrix of 0/1), pos,
cM, chrom, build, and source.
Phase 3 of the 1000 Genomes Project, GRCh38, chromosome 22 positions 20,000,000 to 21,000,000, restricted to biallelic single nucleotide variants with minor allele frequency at least 0.05 in the first 260 samples. Genetic map positions are interpolated from the GRCh38 PLINK maps distributed with BEAGLE.
panel <- kg_reference() dim(panel$haplotypes) range(panel$pos) ## realistic local LD is the point: correlation decays with distance H <- matrix(as.integer(panel$haplotypes), nrow = nrow(panel$haplotypes)) cor(H[, 1], H[, 2])^2 cor(H[, 1], H[, 2000])^2panel <- kg_reference() dim(panel$haplotypes) range(panel$pos) ## realistic local LD is the point: correlation decays with distance H <- matrix(as.integer(panel$haplotypes), nrow = nrow(panel$haplotypes)) cor(H[, 1], H[, 2])^2 cor(H[, 1], H[, 2000])^2
Generate second Bahadur order multivariate Bernoulli random variates with Diagonal Plus Low Rank (dplr) correlation structures.
rb_dplr(n, mu, U, sign = NULL)rb_dplr(n, mu, U, sign = NULL)
n |
positive whole-number count of observations |
mu |
non-empty vector of means strictly between 0 and 1 |
U |
finite outer-product component vector, with the same length as |
sign |
either 1 or -1, selecting |
This generates multivariate Bernoulli (MVB) random vectors with mean
vector 'mu' and correlation matrix where is a diagonal
matrix with values dictated by 'U'. 'mu' must take values in the open unit interval
and 'U' must induce a valid second Bahadur order probability distribution. That is,
there must exist an MVB probability distribution with first moments 'mu' and
standardized central second moments such that all higher order central
moments are zero.
An -by- matrix of binary random variates, where is
the length of 'mu'.
U vectors produced by am_covariance_structure() carry
attr(U, "sign"). Subsetting or coercing U, including with
as.vector(), c(), or U[i], drops that attribute. Because
sign here falls back to +1 when the attribute is absent, doing so
silently converts a disassortative structure into an assortative one, with
no error at any point. If you manipulate U before calling rb_dplr(),
pass sign = -1 explicitly rather than relying on the attribute to
survive.
set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5; min_MAF=.1 ## draw standardized diploid allele substitution effects beta <- scale(rnorm(m))*sqrt(h2_0 / m) ## draw allele frequencies AF <- runif(m, min_MAF, 1 - min_MAF) ## compute unstandardized effects beta_unscaled <- beta/sqrt(2*AF*(1-AF)) ## generate corresponding haploid quantities beta_hap <- rep(beta, each=2) AF_hap <- rep(AF, each=2) ## compute equilibrium outer product covariance component U <- am_covariance_structure(beta, AF, r) ## draw multivariate Bernoulli haplotypes H <- rb_dplr(n, AF_hap, U) ## convert to diploid genotypes G <- H[,seq(1,ncol(H),2)] + H[,seq(2,ncol(H),2)] ## empirical allele frequencies vs target frequencies emp_afs <- colMeans(G)/2 plot(AF, emp_afs) ## construct phenotype heritable_y <- G%*%beta_unscaled nonheritable_y <- rnorm(n, 0, sqrt(1-h2_0)) y <- heritable_y + nonheritable_y ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(heritable_y)/var(y)) h2_eq(r, h2_0)set.seed(1) h2_0 = .5; m = 200; n = 1000; r =.5; min_MAF=.1 ## draw standardized diploid allele substitution effects beta <- scale(rnorm(m))*sqrt(h2_0 / m) ## draw allele frequencies AF <- runif(m, min_MAF, 1 - min_MAF) ## compute unstandardized effects beta_unscaled <- beta/sqrt(2*AF*(1-AF)) ## generate corresponding haploid quantities beta_hap <- rep(beta, each=2) AF_hap <- rep(AF, each=2) ## compute equilibrium outer product covariance component U <- am_covariance_structure(beta, AF, r) ## draw multivariate Bernoulli haplotypes H <- rb_dplr(n, AF_hap, U) ## convert to diploid genotypes G <- H[,seq(1,ncol(H),2)] + H[,seq(2,ncol(H),2)] ## empirical allele frequencies vs target frequencies emp_afs <- colMeans(G)/2 plot(AF, emp_afs) ## construct phenotype heritable_y <- G%*%beta_unscaled nonheritable_y <- rnorm(n, 0, sqrt(1-h2_0)) y <- heritable_y + nonheritable_y ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(heritable_y)/var(y)) h2_eq(r, h2_0)
Generate Bahadur order-2 multivariate Bernoulli random variates with unstructured correlations.
rb_unstr(n, mu, C)rb_unstr(n, mu, C)
n |
positive whole-number count of observations |
mu |
non-empty vector of means strictly between 0 and 1 |
C |
finite symmetric correlation matrix matching the length of |
This generates multivariate Bernoulli (MVB) random vectors with mean vector 'mu' and correlation matrix 'C'. 'mu' must take values in the open unit interval and 'C' must induce a valid second Bahadur order probability distribution. That is, there must exist an MVB probability distribution with first moments 'mu' and standardized central second moments 'C' such that all higher order central moments are zero.
An -by- matrix of binary random variates, where is the
length of 'mu'.
set.seed(1) h2_0 = .5; m = 30; n = 100; r =.5; min_MAF=.1 ## draw standardized diploid allele substitution effects beta <- scale(rnorm(m))*sqrt(h2_0 / m) ## draw allele frequencies AF <- runif(m, min_MAF, 1 - min_MAF) ## compute unstandardized effects beta_unscaled <- beta/sqrt(2*AF*(1-AF)) ## generate corresponding haploid quantities beta_hap <- rep(beta, each=2) AF_hap <- rep(AF, each=2) ## compute equilibrium outer product covariance component U <- am_covariance_structure(beta, AF, r) ## construct Correlation matrix S <- diag(1/sqrt(AF_hap*(1-AF_hap))) DPLR <- U%o%U diag(DPLR) <- 1 C <- cov2cor(S%*%DPLR%*%S) ## draw multivariate Bernoulli haplotypes H <- rb_unstr(n, AF_hap, C) ## convert to diploid genotypes G <- H[,seq(1,ncol(H),2)] + H[,seq(2,ncol(H),2)] ## empirical allele frequencies vs target frequencies emp_afs <- colMeans(G)/2 plot(AF, emp_afs) ## construct phenotype heritable_y <- G%*%beta_unscaled nonheritable_y <- rnorm(n, 0, sqrt(1-h2_0)) y <- heritable_y + nonheritable_y ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(heritable_y)/var(y)) h2_eq(r, h2_0)set.seed(1) h2_0 = .5; m = 30; n = 100; r =.5; min_MAF=.1 ## draw standardized diploid allele substitution effects beta <- scale(rnorm(m))*sqrt(h2_0 / m) ## draw allele frequencies AF <- runif(m, min_MAF, 1 - min_MAF) ## compute unstandardized effects beta_unscaled <- beta/sqrt(2*AF*(1-AF)) ## generate corresponding haploid quantities beta_hap <- rep(beta, each=2) AF_hap <- rep(AF, each=2) ## compute equilibrium outer product covariance component U <- am_covariance_structure(beta, AF, r) ## construct Correlation matrix S <- diag(1/sqrt(AF_hap*(1-AF_hap))) DPLR <- U%o%U diag(DPLR) <- 1 C <- cov2cor(S%*%DPLR%*%S) ## draw multivariate Bernoulli haplotypes H <- rb_unstr(n, AF_hap, C) ## convert to diploid genotypes G <- H[,seq(1,ncol(H),2)] + H[,seq(2,ncol(H),2)] ## empirical allele frequencies vs target frequencies emp_afs <- colMeans(G)/2 plot(AF, emp_afs) ## construct phenotype heritable_y <- G%*%beta_unscaled nonheritable_y <- rnorm(n, 0, sqrt(1-h2_0)) y <- heritable_y + nonheritable_y ## empirical h2 vs expected equilibrium h2 (emp_h2 <- var(heritable_y)/var(y)) h2_eq(r, h2_0)
rbahadur command line scriptReturns the location of the executable shipped with the package, so it can be placed on the search path.
rbahadur_cli_path()rbahadur_cli_path()
A single string giving the path to the script, or "" if the
package was installed without it.
rbahadur_cli_path() ## to put it on your PATH: ## ln -s $(Rscript -e 'cat(rBahadur::rbahadur_cli_path())') ~/bin/rbahadurrbahadur_cli_path() ## to put it on your PATH: ## ln -s $(Rscript -e 'cat(rBahadur::rbahadur_cli_path())') ~/bin/rbahadur
rbahadur command line interfaceDispatches a vector of command line arguments. This is what the shipped
rbahadur script calls; it is exported so the interface can be driven from
R and tested. It returns an exit status rather than terminating the session.
rbahadur_main(args = commandArgs(trailingOnly = TRUE))rbahadur_main(args = commandArgs(trailingOnly = TRUE))
args |
character vector of command line arguments, as returned by
|
Invisibly, an integer exit status: 0 on success, 1 for a usage
error, and 2 for a runtime failure. Usage text goes to stdout when
requested and to stderr when the invocation was wrong.
p <- file.path(tempdir(), "cli_example") rbahadur_main(c("simulate", "--h2", "0.5", "--r", "0.3", "--m", "50", "--n", "40", "--out", p, "--quiet")) rbahadur_main(c("info", p))p <- file.path(tempdir(), "cli_example") rbahadur_main(c("simulate", "--h2", "0.5", "--r", "0.3", "--m", "50", "--n", "40", "--out", p, "--quiet")) rbahadur_main(c("info", p))
write_genotypes()
Read genotypes from a binary file written by write_genotypes()
read_genotypes(path)read_genotypes(path)
path |
file prefix, the same value passed to |
An integer matrix with individuals in rows and variants in columns, reconstructed to the same orientation regardless of the on-disk layout.
X <- matrix(sample(0:2, 20, replace = TRUE), nrow = 4) p <- file.path(tempdir(), "example_genotypes") write_genotypes(X, p, format = "variant") read_genotypes(p)X <- matrix(sample(0:2, 20, replace = TRUE), nrow = 4) p <- file.path(tempdir(), "example_genotypes") write_genotypes(X, p, format = "variant") read_genotypes(p)
Reads a biallelic VCF and returns a panel in the form am_mosaic() expects.
Phased genotypes such as 0|1 are strongly recommended because the mosaic
copies haplotypes rather than genotypes. Unphased genotypes such as 0/1
are accepted with a warning and their written allele order is treated as if
it were phase.
vcf_to_panel( vcf, map = NULL, min_maf = 0.05, max_markers = NULL, max_samples = NULL )vcf_to_panel( vcf, map = NULL, min_maf = 0.05, max_markers = NULL, max_samples = NULL )
vcf |
path to a VCF, optionally gzipped |
map |
optional path to a PLINK-format genetic map with columns
chromosome, marker, centimorgans, and base pair position. Without one, the
panel carries no |
min_maf |
drop markers whose minor allele frequency in the panel falls
below this. Must lie in |
max_markers |
if given, thin evenly to at most this many markers |
max_samples |
if given, keep only the first this many samples |
A panel list suitable for am_mosaic(), including chromosome, ID,
reference allele, and alternate allele metadata for each retained marker.
## a tiny phased VCF written on the fly vcf <- tempfile(fileext = ".vcf") writeLines(c( "##fileformat=VCFv4.2", paste(c("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO", "FORMAT", "s1", "s2", "s3", "s4"), collapse = "\t"), paste(c("22", "100", ".", "A", "G", ".", ".", ".", "GT", "0|1", "1|1", "0|0", "1|0"), collapse = "\t"), paste(c("22", "200", ".", "C", "T", ".", ".", ".", "GT", "1|0", "0|1", "1|1", "0|0"), collapse = "\t")), vcf) panel <- vcf_to_panel(vcf, min_maf = 0) dim(panel$haplotypes)## a tiny phased VCF written on the fly vcf <- tempfile(fileext = ".vcf") writeLines(c( "##fileformat=VCFv4.2", paste(c("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO", "FORMAT", "s1", "s2", "s3", "s4"), collapse = "\t"), paste(c("22", "100", ".", "A", "G", ".", ".", ".", "GT", "0|1", "1|1", "0|0", "1|0"), collapse = "\t"), paste(c("22", "200", ".", "C", "T", ".", ".", ".", "GT", "1|0", "0|1", "1|1", "0|0"), collapse = "\t")), vcf) panel <- vcf_to_panel(vcf, min_maf = 0) dim(panel$haplotypes)
Write genotypes to a binary file
write_genotypes(X, path, format = c("individual", "variant", "bed"))write_genotypes(X, path, format = c("individual", "variant", "bed"))
X |
an integer matrix of genotypes with individuals in rows and variants in columns, taking values 0, 1, or 2 |
path |
non-empty file prefix in an existing directory. Layout
|
format |
on-disk layout. |
Because this function receives no marker annotations, PLINK .bim
output uses placeholder chromosome, position, and allele values. PLINK files
written by am_mosaic() instead preserve the reference panel's available
chromosome, physical position, genetic map, ID, and allele metadata.
path, invisibly.
X <- matrix(sample(0:2, 20, replace = TRUE), nrow = 4) p <- file.path(tempdir(), "example_genotypes") write_genotypes(X, p) identical(read_genotypes(p), X)X <- matrix(sample(0:2, 20, replace = TRUE), nrow = 4) p <- file.path(tempdir(), "example_genotypes") write_genotypes(X, p) identical(read_genotypes(p), X)