Списки резюме из Rentrez перестают работать после слияния с помощью append()

tl;dr: Чем отличается список резюме, созданный rentrezи почему указанные списки перестают работать с другими rentrez функции после того, как они объединены с использованием append()?

Я захожу в Pubmed используя rentrez, Я могу без проблем искать публикации и загружать резюме. Тем не менее, должно быть что-то особенное в списке резюме, который я не понимаю, потому что вещи распадаются, когда я использовал append() попытаться объединить списки. Я не смог выяснить, что это за разница, прочитав документацию. Вот код, который позволяет без проблем искать в Pubmed и скачивать записи:

# set search term and retmax
term_set <- '"Transcription, Genetic"[Mesh] AND "Regulatory Sequences, Nucleic Acid"[Mesh] AND 2017:2018[PDAT]'
retmax_set <- 500
# search pubmed using web history
search.l <- entrez_search(db = "pubmed", term = term_set, use_history = T)
# get summaries of search hits using web history 
for (seq_start in seq(0, search.l$count, retmax_set)) {
    if (seq_start == 0) {summary.l <- list()} 
    summary.l[[length(summary.l)+1]] <- entrez_summary(
        db = "pubmed", 
        web_history = search.l$web_history, 
        retmax = retmax_set, 
        retstart = seq_start
    )
}

Однако, используя summary.l <- list() а потом summary.l[[length(summary.l)+1]] <- entrez_summary(... приводит к списку списков резюме (3 подсписка, в этом поиске). Это приводит к множественным for зацикливается на последующих этапах извлечения данных (ниже) и представляет собой непривлекательную структуру данных.

# extract desired information from esummary, convert to dataframe
for (i in 1:length(summary.l)) {
    if (i == 1) {faut.laut.l <- list()}
    faut.laut <- summary.l[[i]] %>% 
        extract_from_esummary(
            c("uid", "sortfirstauthor", "lastauthor"), 
            simplify = F
        )
    faut.laut.l <- c(faut.laut.l, faut.laut)
}
faut.laut.df <- rbindlist(faut.laut.l)

С помощью append() в приведенном ниже коде приводится единый список всех 1334 резюме, избегая подсписков.

# get summaries of search hits using web history 
for (seq_start in seq(0, search.l$count, retmax_set)) {
    if (seq_start == 0) {
        summary.append.l <- entrez_summary(
            db = "pubmed", 
            web_history = search.l$web_history, 
            retmax = retmax_set, 
            retstart = seq_start
        )
    } 
    summary.append.l <- append(
        summary.append.l,
        entrez_summary(
            db = "pubmed", 
            web_history = search.l$web_history, 
            retmax = retmax_set, 
            retstart = seq_start
        )
    )
}

Однако на следующем этапе extract_from_esummary() выдает ошибку, хотя в документации сказано, что аргумент esummaries должен быть список основных объектов.

# extract desired information from esummary, convert to dataframe
faut.laut.append.l <- extract_from_esummary(
    esummaries = summary.append.l,
    elements = c("uid", "sortfirstauthor", "lastauthor"), 
    simplify = F
)
Error in UseMethod("extract_from_esummary", esummaries) : 
no applicable method for 'extract_from_esummary' applied to an object of class "list"

faut.laut.append.df <- rbindlist(faut.laut.append.l)
Error in rbindlist(faut.laut.append.l) : 
object 'faut.laut.append.l' not found

Поиск, который дает менее 500 записей, может быть выполнен за один вызов entrez_summary() и не требует объединения списков. В результате код ниже работает.

# set search term and retmax
term_set_small <- 'kadonaga[AUTH]'
retmax_set <- 500
# search pubmed using web history
search_small <- entrez_search(db = "pubmed", term = term_set_small, use_history = T)
# get summaries from search with <500 hits
summary_small <- entrez_summary(
    db = "pubmed", 
    web_history = search_small$web_history, 
    retmax = retmax_set
)
# extract desired information from esummary, convert to dataframe
faut.laut_small <- extract_from_esummary(
    esummaries = summary_small,
    elements = c("uid", "sortfirstauthor", "lastauthor"), 
    simplify = F
)
faut.laut_small.df <- rbindlist(faut.laut_small)

Почему append() сломать резюме, и можно ли этого избежать? Благодарю.

1 ответ

Решение

Документация для extract_from_esummary немного запутывает это. Что ему действительно нужно, так это либо esummary объект или esummary_list, Поскольку esummary сам объект наследуется от списка, я не думаю, что мы можем легко иметь extract_from_esummary работать над любым списком, который брошен на это. Я исправлю документы и, возможно, подумаю над лучшим дизайном для объектов.

Чтобы исправить эту конкретную проблему, есть несколько исправлений. Во-первых, вы можете просто переклассифицировать список резюме

class(summary.append.l) <- c("list", "esummary_list")
extract_from_esummary(summary.append.l, "sortfirstauthor")

Должен сделать свое дело. Другим вариантом может быть извлечение соответствующих данных, прежде чем делать какие-либо добавления. Это что-то похожее на ваш пример с более lapply и менее for

all_the_summs <- lapply(seq(0,50,5),  function(s) {
    entrez_summary(db="pubmed", 
                   web_history=search.l$web_history, 
                   retmax=5,  retstart=s)
})
desired_fields <- lapply(all_the_summs, extract_from_esummary, c("uid", "sortfirstauthor", "lastauthor"), simplify=FALSE)  
res <- do.call(cbind.data.frame, desired_fields)

Надеюсь, что это дает путь вперед.

Другие вопросы по тегам