эффективное подмножество в R phyloseq, игнорируя пропущенные параметры - PullRequest
0 голосов
/ 25 октября 2019

Я много использую phyloseq для своей работы. Мои наборы данных часто содержат несколько условий или параметров, которые необходимо анализировать одинаковым образом (например, один и тот же график для бактерий летом или зимой и в озере 1 или озере 2), поэтому я хотел использовать для этого функции. Я написал функцию подмножества, которая позволяет мне комбинировать несколько параметров, зацикливая их. Вывод сохраняется в списках для дальнейшего анализа.

Однако это выглядит довольно неуклюже. Поэтому мой первый вопрос касается улучшения функции.

1) В частности, мне интересно, является ли

a) использование нескольких for loops для генерации подмножеств хорошей идеей.

b) Также можно оптимизировать комбинацию for loops и lapply. И

в) может быть, есть лучший способ не допустить, чтобы существующие списки снова не были распознаны с новой итерацией тех же объектов снова? Я реализовал это, поскольку у меня было много-много тестовых выполнений при разработке кода

Вопрос о том, являются ли циклы медленнее, чем применяются вообще, обсуждался здесь: lapply против цикла - производительность R

Я думаю, phyloseq внутренне вызывает which, так что это не должно быть phyloseq конкретным решением.

2) Мой второй вопрос будет о том, как обращаться с делом, если не всепараметры поиска присутствуют во всех подмножествах? Таким образом, в приведенном ниже примере комбинация «датский» и «М» сломалась бы, если бы не было датских мужчин. Я хотел бы избежать этого, и в этом примере вместо 4 подмножеств всего используется 3 (датский x F, американский x F, американский x M). На данный момент функция должна быть адаптирована к каждому специальному подмножеству, которое разрушает цель ее написания.

library(phyloseq)
data(enterotype)
# reduce the size of the data set
phyloseq <- filter_taxa(enterotype, function (x) {sum(x > 0.001) >= 1}, prune = TRUE)

# arguments for the subsetting function
phyloseq_object <- phyloseq
Nationality <- c("american", "danish")
Gender <- c("F", "M")

# define a function to obtain sample subsets from the phyloseq object 
# per combination of parameters
get_sample_subsets <- function(phyloseq_object, nation, gender) {
  sample_subset <- sample_data(phyloseq_object)[ which(sample_data(phyloseq_object)$Nationality == nation &
    sample_data(phyloseq_object)$Gender == gender),]
  phyloseq_subset <- merge_phyloseq(tax_table(phyloseq_object),
    otu_table(phyloseq_object),
    #refseq(phyloseq_object),
    sample_subset)
  phyloseq_subset2 <- filter_taxa(phyloseq_subset, function (x) {sum(x > 0) >= 1 }, prune = TRUE)
  return(phyloseq_subset2)
}

# here we pass the arguments for subsetting over two for loops
# to create all possible combinations of the subset parameters etc.
# the subsets are stored within a list, which has to be empty before running the loops 
sample_subset_list <- list()
if(length(sample_subset_list) == 0) {
  for (nations in Nationality) {
    for (gender in Gender) {
      tmp <- get_sample_subsets(phyloseq_object = phyloseq_object,
        nation = nations, gender = gender)
      sample_subset_list[[paste(nations, gender, sep = "_")]] <- tmp
    }
  }
  print(sample_subset_list)
} else {
  print("list is not empty, abort to prevent appending...")
}

# You could now for example use the output to calculate ordinations for each subset (this data set has too few entries per subset for that)

# create a list where the distance metrics for the sample subsets are stored
ordination_nmds <- list()
ordination_nmds <- lapply(sample_subset_list, ordinate, method = "NMDS",
  dist = "bray", try = 100, autotransform = TRUE)

1 Ответ

0 голосов
/ 14 ноября 2019

Работает для S3, но не для S4 (см. Комментарии)

Поскольку я не знаком с S4, я могу удалить этот ответ, если что-то получится лучше.

Исходя из моего комментария, кое-что может вам помочь. Пожалуйста, дайте мне знать, если вам нужно лучшее решение или оно не отвечает вашей проблеме.

# I changed the data because "phyloseq" package require further install
    ex_data = mtcars

# this line might replace your "get_sample_subsets" function and your loop to check if they are empty lists
# You can modify the elements inside list(...) to get the wanted subsets, it is very flexible
    sampled_data = split(ex_data, list(ex_data$cyl, ex_data$vs), drop = TRUE) # note the drop = TRUE, to avoid "empty" elements
...