You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When I replace linda function with a modified version accepting accessory arguments (this code is a copy of https://github.com/cafferychen777/MicrobiomeStat/blob/main/R/linda.R, only difference with the current linda() version is the accessory argument ... after verbose = TRUEin function call), mStat_generate_report_single() runs normally until the end.
Modified linda version:
linda_modified <- function(feature.dat, meta.dat, phyloseq.obj = NULL, formula, feature.dat.type = c("count", "proportion","other"),
prev.filter = 0, mean.abund.filter = 0, max.abund.filter = 0,
is.winsor = TRUE, outlier.pct = 0.03,
adaptive = TRUE, zero.handling = c("pseudo-count", "imputation"),
pseudo.cnt = 0.5, corr.cut = 0.1,
p.adj.method = "BH", alpha = 0.05,
n.cores = 1, verbose = TRUE, ...) {
############################################
# only difference with linda() is the accessory argument `...` after verbose = TRUE
############################################
feature.dat.type <- match.arg(feature.dat.type)
if (!is.null(phyloseq.obj)) {
feature.dat.type <- "count"
feature.dat <- phyloseq.obj@otu_table %>%
as.data.frame() %>%
as.matrix()
meta.dat <- phyloseq.obj@sam_data %>% as.matrix() %>%
as.data.frame()
}
if (any(is.na(feature.dat))) {
stop(
"The feature table contains NA values. Please remove or handle them before proceeding.\n"
)
}
allvars <- all.vars(as.formula(formula))
Z <- as.data.frame(meta.dat[, allvars])
###############################################################################
# Filter sample
keep.sam <- which(rowSums(is.na(Z)) == 0)
Y <- feature.dat[, keep.sam]
Z <- as.data.frame(Z[keep.sam, ])
names(Z) <- allvars
# Filter features
temp <- t(t(Y) / colSums(Y))
if (feature.dat.type == "other" & (max.abund.filter != 0 | mean.abund.filter != 0 | prev.filter != 0 )){
message("Note: Since feature.dat.type is set to 'other', all filters (max.abund.filter, mean.abund.filter, and prev.filter) are reset to 0.")
max.abund.filter <- 0
mean.abund.filter <- 0
prev.filter <- 0
}
keep.tax <- rowMeans(temp != 0) >= prev.filter & rowMeans(temp) >= mean.abund.filter & matrixStats::rowMaxs(temp) >= max.abund.filter
names(keep.tax) <- rownames(Y)
rm(temp)
if (verbose) {
message(
sum(!keep.tax), " features are filtered!\n"
)
}
Y <- Y[keep.tax, ]
n <- ncol(Y)
m <- nrow(Y)
## some samples may have zero total counts after screening taxa
if (any(colSums(Y) == 0)) {
ind <- which(colSums(Y) > 0)
Y <- Y[, ind]
Z <- as.data.frame(Z[ind, ])
names(Z) <- allvars
keep.sam <- keep.sam[ind]
n <- ncol(Y)
}
if (verbose) {
message(
"The filtered data has ", n, " samples and ", m, " features that will be tested!\n"
)
}
if (sum(rowSums(Y != 0) <= 2) != 0) {
warning(
"Some features have less than 3 nonzero values!\n",
"They have virtually no statistical power. You may consider filtering them in the analysis!\n"
)
}
###############################################################################
## scaling numerical variables
ind <- sapply(1:ncol(Z), function(i) is.numeric(Z[, i]))
Z[, ind] <- scale(Z[, ind])
## winsorization
if (is.winsor) {
Y <- winsor.fun(Y, 1 - outlier.pct, feature.dat.type)
}
##
if (grepl("\\(", formula)) {
random.effect <- TRUE
} else {
random.effect <- FALSE
}
if (is.null(rownames(feature.dat))) {
taxa.name <- (1:nrow(feature.dat))[keep.tax]
} else {
taxa.name <- rownames(feature.dat)[keep.tax]
}
if (is.null(rownames(meta.dat))) {
samp.name <- (1:nrow(meta.dat))[keep.sam]
} else {
samp.name <- rownames(meta.dat)[keep.sam]
}
## handling zeros
if (feature.dat.type == "count") {
if (any(Y == 0)) {
N <- colSums(Y)
if (adaptive) {
logN <- log(N)
if (random.effect) {
tmp <- lmer(as.formula(paste0("logN", formula)), Z)
} else {
tmp <- lm(as.formula(paste0("logN", formula)), Z)
}
corr.pval <- coef(summary(tmp))[-1, "Pr(>|t|)"]
if (any(corr.pval <= corr.cut)) {
if (verbose) {
message("Imputation approach is used.")
}
zero.handling <- "Imputation"
} else {
if (verbose) {
message("Pseudo-count approach is used.")
}
zero.handling <- "Pseudo-count"
}
}
if (zero.handling == "imputation") {
N.mat <- matrix(rep(N, m), nrow = m, byrow = TRUE)
N.mat[Y > 0] <- 0
tmp <- N[max.col(N.mat)]
Y <- Y + N.mat / tmp
} else {
Y <- Y + pseudo.cnt
}
}
}
if (feature.dat.type == "proportion") {
if (any(Y == 0)) {
# Half minimum approach
Y <- t(apply(Y, 1, function(x) {
x[x == 0] <- 0.5 * min(x[x != 0])
return(x)
}))
colnames(Y) <- samp.name
rownames(Y) <- taxa.name
}
}
## CLR transformation
logY <- log2(Y)
W <- t(logY) - colMeans(logY)
## linear regression
# oldw <- getOption('warn')
# options(warn = -1)
if (!random.effect) {
if (verbose) {
message("Fit linear models ...")
}
suppressMessages(fit <- lm(as.formula(paste0("W", formula)), Z))
res <- do.call(rbind, coef(summary(fit)))
df <- rep(n - ncol(model.matrix(fit)), m)
} else {
if (verbose) {
message("Fit linear mixed effects models ...")
}
fun <- function(i) {
w <- W[, i]
suppressMessages(fit <- lmer(as.formula(paste0("w", formula)), Z))
coef(summary(fit))
}
if (n.cores > 1) {
res <- mclapply(c(1:m), function(i) fun(i), mc.cores = n.cores)
} else {
suppressMessages(res <- foreach(i = 1:m) %do% fun(i))
}
res <- do.call(rbind, res)
}
# options(warn = oldw)
res.intc <- res[which(rownames(res) == "(Intercept)"), ]
rownames(res.intc) <- NULL
baseMean <- 2^res.intc[, 1]
baseMean <- baseMean / sum(baseMean) * 1e6
output.fun <- function(x) {
res.voi <- res[which(rownames(res) == x), ]
rownames(res.voi) <- NULL
if (random.effect) {
df <- res.voi[, 3]
}
log2FoldChange <- res.voi[, 1]
lfcSE <- res.voi[, 2]
# oldw <- getOption('warn')
# options(warn = -1)
suppressMessages(bias <- modeest::mlv(sqrt(n) * log2FoldChange,
method = "meanshift", kernel = "gaussian"
) / sqrt(n))
# options(warn = oldw)
log2FoldChange <- log2FoldChange - bias
stat <- log2FoldChange / lfcSE
pvalue <- 2 * pt(-abs(stat), df)
padj <- p.adjust(pvalue, method = p.adj.method)
reject <- padj <= alpha
output <- cbind.data.frame(baseMean, log2FoldChange, lfcSE, stat, pvalue, padj, reject, df)
rownames(output) <- taxa.name
return(list(bias = bias, output = output))
}
variables <- unique(rownames(res))[-1]
variables.n <- length(variables)
bias <- rep(NA, variables.n)
output <- list()
for (i in 1:variables.n) {
tmp <- output.fun(variables[i])
output[[i]] <- tmp[[2]]
bias[i] <- tmp[[1]]
}
names(output) <- variables
rownames(Y) <- taxa.name
colnames(Y) <- samp.name
rownames(Z) <- samp.name
if (verbose) {
message("Completed.")
}
return(list(variables = variables, bias = bias, output = output, feature.dat.use = Y, meta.dat.use = Z))
}
Replacing linda version in the MicrobiomeStat namespace:
Thank you for reaching out with your issue. I understand the problem you're encountering with the mStat_generate_report_single() function and the linda() call.
I actually identified and addressed this issue three days ago. You can view the specific commit where the changes were made here: Commit on GitHub.
To resolve the issue you're experiencing, please update your package to the latest version. This update includes the modified linda() function that supports the additional arguments causing the error.
Let me know if you encounter any further problems after updating, or if there is anything else I can assist you with!
mStat_generate_report_single()
fails due invalid call tolinda()
inMicrobiomeStat_1.1.3
:When I replace linda function with a modified version accepting accessory arguments (this code is a copy of https://github.com/cafferychen777/MicrobiomeStat/blob/main/R/linda.R, only difference with the current
linda()
version is the accessory argument...
afterverbose = TRUE
in function call),mStat_generate_report_single()
runs normally until the end.Modified linda version:
Replacing linda version in the MicrobiomeStat namespace:
I also need to define a
winsor.fun
in the current environment -this is just a copy of thewinsor.fun
found in https://github.com/cafferychen777/MicrobiomeStat/blob/main/R/linda.R-sessionInfo()
:The text was updated successfully, but these errors were encountered: