Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 140 additions & 29 deletions R/AlphaPart.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@
#' @param colPath Numeric or character, position or name of a column
#' holding path information.
#' @param colBV Numeric or character, position(s) or name(s) of
#' column(s) holding genetic Values.
#' column(s) holding genetic values.
#' @param colPaternalBV Numeric or character, position(s) of column(s)
#' holding the paternal genetic values for IBD partitioning.
#' @param colMaternalBV Numeric or character, position(s) of column(s)
#' holding the maternal genetic values for IBD partitioning..
#' @param colBy Numeric or character, position or name of a column
#' holding group information (see details).
#'
Expand Down Expand Up @@ -164,6 +168,8 @@ AlphaPart <- function(
colMid = 3,
colPath = 4,
colBV = 5:ncol(x),
colPaternalBV = NULL,
colMaternalBV = NULL,
colBy = NULL
) {
## Test if the data is a data.frame
Expand All @@ -181,6 +187,15 @@ AlphaPart <- function(
"arguments 'colId', 'colFid', 'colMid', 'colPath', and 'colBy' must be of length 1"
)
}

if (!is.null(colPaternalBV) | !is.null(colMaternalBV)){
if (is.null(colPaternalBV) | is.null(colMaternalBV)){
stop("Both 'colPaternalBV' and 'colMaternalBV' must be provided for IBD partitioning.")
}
gameticPartition <- TRUE
} else {
gameticPartition <- FALSE
}

if (is.null(colBy)) {
groupSummary <- FALSE
Expand Down Expand Up @@ -237,6 +252,24 @@ AlphaPart <- function(
}
testN <- NULL # not needed anymore
}

if (gameticPartition){
if(!is.numeric(colPaternalBV)){
testN <- length(colPaternalBV)
colPaternalBV <- which(colnames(x) %in% colPaternalBV)
if (length(colPaternalBV) != testN) {
stop("Identification not valid for 'colPaternalBV' column(s) name", call. = FALSE)
}
}
if(!is.numeric(colMaternalBV)){
testN <- length(colMaternalBV)
colMaternalBV <- which(colnames(x) %in% colMaternalBV)
if (length(colMaternalBV) != testN) {
stop("Identification not valid for 'colMaternalBV' column(s) name", call. = FALSE)
}
}
testN <- NULL # not needed anymore
}

## --- Sort and recode pedigree ---
## Make sure that identifications are numeric if recode=FALSE
Expand All @@ -253,6 +286,35 @@ AlphaPart <- function(
stop("colBV columns must be numeric!")
str(x)
}

## If gametic partitioning, make sure that colPaternalBV and colMaternalBV:
## - are numeric
## - the same length as colBV
## - the columns sum to the colBV columns
if (gameticPartition){
test <- !sapply(x[, c(colPaternalBV)], is.numeric)
if (any(test)){
stop("colPaternalBV columns must be numeric!")
str(x)
}
test <- !sapply(x[, c(colMaternalBV)], is.numeric)
if (any(test)){
stop("colMaternalBV columns must be numeric!")
str(x)
}
test <- length(colPaternalBV) != length(colMaternalBV)
if (any(test)){
stop("colPaternalBV and colMaternalBV must be of the same length!")
}
test <- length(colPaternalBV) != length(colBV)
if (any(test)){
stop("colPaternalBV and colMaternalBV must be of the same length as colBV!")
}
test <- any(abs(x[, c(colBV)] - x[, c(colPaternalBV)] - x[, c(colMaternalBV)]) > 1e-8)
if (any(test)){
stop("The sum of colPaternalBV and colMaternalBV must be equal to colBV for each individual!")
}
}

## Sort so that parents precede children
if (sort) {
Expand Down Expand Up @@ -307,7 +369,14 @@ AlphaPart <- function(
}
}
}
y <- cbind(y, as.matrix(x[, colBV]))

if (!gameticPartition){
y <- cbind(y, as.matrix(x[, colBV]))
nGP <- 1 # Number of genetic partitions: total
} else {
y <- cbind(y, as.matrix(x[, colBV]), as.matrix(x[, colPaternalBV]), as.matrix(x[, colMaternalBV]))
nGP <- 3 # Number of genetic partitions: total, paternal, maternal
}

## Test if father and mother codes precede children code -
## computational engine needs this
Expand Down Expand Up @@ -430,6 +499,7 @@ AlphaPart <- function(
nI = nI,
nP = nP,
nT = nT,
nGP = nGP,
ped = y,
P = as.integer(P),
Px = as.integer(cumsum(c(0, rep(nP, nT - 1))))
Expand All @@ -448,14 +518,24 @@ AlphaPart <- function(
nG = nG,
ped = y,
P = as.integer(P),
Px = as.integer(cumsum(c(0, rep(nP, nT - 1))))
Px = as.integer(cumsum(c(0, rep(nP, nT - 1)))),
g = g
)
}

## Assign nice column names
colnames(tmp$pa) <- paste(lT, "_pa", sep = "")
colnames(tmp$ms) <- paste(lT, "_ms", sep = "")
colnames(tmp$xa) <- c(t(outer(lT, lP, paste, sep = "_")))
if (!gameticPartition){
colnames(tmp$pa) <- paste(lT, "_pa", sep = "")
colnames(tmp$ms) <- paste(lT, "_ms", sep = "")
colnames(tmp$xa) <- c(t(outer(lT, lP, paste, sep = "_")))
} else {
#lPT <- colnames(x[, c(colBV, colPaternalBV, colMaternalBV), drop=FALSE])
lP <- c(lP, paste0(lP, "_paternal"), paste0(lP, "_maternal"))
lPT <- unlist(lapply(c("","_paternal", "_maternal"), function(s) paste0(lT, s)))
colnames(tmp$pa) <- paste(lPT, "_pa", sep="")
colnames(tmp$ms) <- paste(lPT, "_ms", sep="")
colnames(tmp$xa) <- c(t(outer(lT, lP, paste, sep = "_")))
}

## --- Massage results ---

Expand All @@ -466,34 +546,64 @@ AlphaPart <- function(
colP <- colnames(tmp$pa)
colM <- colnames(tmp$ms)
colX <- colnames(tmp$xa)

for (j in 1:nT) {
## j <- 1
Py <- seq(t + 1, t + nP)
ret[[j]] <- cbind(tmp$pa[-1, j], tmp$ms[-1, j], tmp$xa[-1, Py])
colnames(ret[[j]]) <- c(colP[j], colM[j], colX[Py])
t <- max(Py)

if (!gameticPartition) {
for (j in 1:nT) {
## j <- 1
Py <- seq(t + 1, t + nP)
ret[[j]] <- cbind(tmp$pa[-1, j], tmp$ms[-1, j], tmp$xa[-1, Py])
colnames(ret[[j]]) <- c(colP[j], colM[j], colX[Py])
t <- max(Py)
}
} else {
t <- 0
for (j in 1:nT) {
## j <- 1
Py <- seq(t+1, j*nGP*nP)
pams <- c(j, j+nT, j+2*nT)
ret[[j]] <- cbind(tmp$pa[-1, pams], tmp$ms[-1, pams], tmp$xa[-1, Py])
colnames(ret[[j]]) <- c(colP[pams], colM[pams], colX[Py])
t <- max(Py)
}
}
tmp <- NULL # not needed anymore

tmp <- NULL # not needed anymore

## Add initial data

if (!groupSummary) {
for (i in 1:nT) {
## Hassle in order to get all columns and to be able to work with
## numeric or character column "names"
colX <- colX2 <- colnames(x)
names(colX) <- colX
names(colX2) <- colX2
## ... put current agv in the last column in original data
colX <- c(colX[!(colX %in% colX[colBV[i]])], colX[colBV[i]])
## ... remove other traits
colX <- colX[
!(colX %in%
colX2[(colX2 %in% colX2[colBV]) & !(colX2 %in% colX2[colBV[i]])])
]
ret[[i]] <- cbind(x[, colX], as.data.frame(ret[[i]]))
rownames(ret[[i]]) <- NULL
if (!gameticPartition) {
for (i in 1:nT) {
## Hassle in order to get all columns and to be able to work with
## numeric or character column "names"
colX <- colX2 <- colnames(x)
names(colX) <- colX
names(colX2) <- colX2
## ... put current agv in the last column in original data
colX <- c(colX[!(colX %in% colX[colBV[i]])], colX[colBV[i]])
## ... remove other traits
colX <- colX[
!(colX %in%
colX2[(colX2 %in% colX2[colBV]) & !(colX2 %in% colX2[colBV[i]])])
]
ret[[i]] <- cbind(x[, colX], as.data.frame(ret[[i]]))
rownames(ret[[i]]) <- NULL
}
} else {
for (i in 1:nT) {
## Hassle in order to get all columns and to be able to work with
## numeric or character column "names"
colX <- colX2 <- colnames(x)
names(colX) <- colX; names(colX2) <- colX2
## ... put current agv in the last three columns in original data
colX <- c(colX[!(colX %in% c(colX[colBV[i]], colX[colPaternalBV[i]], colX[colMaternalBV[i]]))],
colX[colBV[i]], colX[colPaternalBV[i]], colX[colMaternalBV[i]])
## ... remove other traits
colX <- colX[!(colX %in% colX2[(colX2 %in% c(colX2[colBV], colX2[colPaternalBV], colX2[colMaternalBV])) & !
(colX2 %in% c(colX2[colBV[i]], colX2[colPaternalBV[i]], colX2[colMaternalBV[i]]))])]
ret[[i]] <- cbind(x[, colX], as.data.frame(ret[[i]]))
rownames(ret[[i]]) <- NULL
}
}
}

Expand All @@ -507,6 +617,7 @@ AlphaPart <- function(
lP = lP,
nT = nT,
lT = lT,
gameticPartition = gameticPartition,
warn = NULL
)
## names(ret)[nT+1] <- "info"
Expand Down
4 changes: 2 additions & 2 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

AlphaPartDrop <- function(c1, c2, nI, nP, nT, ped, P, Px) {
.Call(`_AlphaPart_AlphaPartDrop`, c1, c2, nI, nP, nT, ped, P, Px)
AlphaPartDrop <- function(c1, c2, nI, nP, nT, nGP, ped, P, Px) {
.Call(`_AlphaPart_AlphaPartDrop`, c1, c2, nI, nP, nT, nGP, ped, P, Px)
}

AlphaPartDropGroup <- function(c1, c2, nI, nP, nT, nG, ped, P, Px, g) {
Expand Down
9 changes: 6 additions & 3 deletions R/methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ summary.AlphaPart <- function(
nT = nT,
lT = lT,
by = by,
gameticPartition = object$info$gameticPartition,
warn = object$info$warn,
labelSum = labelSum
)
Expand Down Expand Up @@ -526,6 +527,8 @@ plot.summaryAlphaPart <-
nP <- x$info$nP + x$info$nCov
ret <- vector(mode = "list", length = nT)
names(ret) <- x$info$lT

ifelse(x$info$gameticPartition, nGP <- 3, nGP <- 1)

## Axis labels
if (!is.null(xlab) && length(xlab) > 1)
Expand Down Expand Up @@ -613,8 +616,8 @@ plot.summaryAlphaPart <-
}
## Line type
if (is.null(lineTypeList)) {
if (length(lineType) < nP) {
lineType <- c(1, rep(x = lineType, times = nP))
if (length(lineType) < nP*nGP) {
lineType <- c(1, rep(x = lineType, times = nP*nGP))
} else {
lineType <- c(1, lineType)
}
Expand Down Expand Up @@ -643,7 +646,7 @@ plot.summaryAlphaPart <-
if (sortValue) {
nC <- ncol(tmp0)
pathStat <- sapply(
X = tmp0[, (nC - nP + 1):nC],
X = tmp0[, (nC - (nP*nGP) + 1):nC],
FUN = sortValueFUN,
na.rm = TRUE
)
Expand Down
10 changes: 9 additions & 1 deletion man/AlphaPart.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 30 additions & 8 deletions src/AlphaPartDrop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
using namespace Rcpp;

// [[Rcpp::export]]
List AlphaPartDrop(double c1, double c2, int nI, int nP, int nT,
List AlphaPartDrop(double c1, double c2, int nI, int nP, int nT, int nGP,
NumericMatrix ped, IntegerVector P, IntegerVector Px) {
// --- Temp ---

int i, j, t, p;
int i, j, t, p, pt=0, mt=0, k;

// --- Outputs ---

NumericMatrix pa(nI+1, nT); // Parent average
NumericMatrix ms(nI+1, nT); // Mendelian sampling
NumericMatrix xa(nI+1, nP*nT); // Partitions
NumericMatrix pa(nI+1, nT*nGP); // Parent average
NumericMatrix ms(nI+1, nT*nGP); // Mendelian sampling
NumericMatrix xa(nI+1, nP*nT*nGP); // Partitions
// NOTE: Rcpp::NumericMatrix is filled by 0s by default

// TODO: Maybe we want an algorithm that works on one trait at a time to save on memory?
Expand All @@ -22,7 +22,6 @@ List AlphaPartDrop(double c1, double c2, int nI, int nP, int nT,
// https://github.com/AlphaGenes/AlphaPart/issues/13

// --- Compute ---

for(i = 1; i < nI+1; i++) {
for(t = 0; t < nT; t++) {
// Parent average (PA)
Expand All @@ -31,18 +30,41 @@ List AlphaPartDrop(double c1, double c2, int nI, int nP, int nT,

// Mendelian sampling (MS)
ms(i, t) = ped(i, 3+t) - pa(i, t);

// Gametic partition
if (nGP ==3) {
pt = t + nT; // paternal trait index
mt = t + 2*nT; // maternal trait index
pa(i, pt) = c1 * ped(ped(i,1), 3+pt) + c1 * ped(ped(i,1), 3+mt);
pa(i, mt) = c2 * ped(ped(i,2), 3+pt) + c2 * ped(ped(i,2), 3+mt);
ms(i, mt) = ped(i, 3+mt) - pa(i, mt);
ms(i, pt) = ped(i, 3+pt) - pa(i, pt);
}

// Parts

// ... for the MS part
j = Px[t] + P[i];
j = nGP*Px[t] + P[i];
xa(i, j) = ms(i, t);

if (nGP == 3) {
j = nGP*Px[t] + P[i] + nP;
xa(i, j) = ms(i, pt);
j = nGP*Px[t] + P[i] + nP*2;
xa(i, j) = ms(i, mt);
}

// ... for the PA parts
for(p = 0; p < nP; p++) {
j = Px[t] + p;
j = nGP*Px[t] + p;
xa(i, j) += c1 * xa(ped(i, 1), j) +
c2 * xa(ped(i, 2), j);
if (nGP == 3) {
j = nGP*Px[t] + p + nP;
k = nGP*Px[t] + p + nP*2;
xa(i, j) += c1 * xa(ped(i, 1), j) + c1 * xa(ped(i, 1), k);
xa(i, k) += c2 * xa(ped(i, 2), j) + c2 * xa(ped(i, 2), k);
}
}
}
}
Expand Down
Loading