Сохранение графиков, сгенерированных из списка с использованием имен в списке с использованием lapply

#r #ggplot2

#r #ggplot2

Вопрос:

У меня есть список таблиц данных, каждая из которых содержит данные в одном формате и каждая из которых имеет уникальное имя. Пример ниже:

 > head(list$table1)
        gene     logFC negLogPval
    1   CROT -1.546082   6.405688
    2 CASC15 -1.718302   5.501062
    3  ITGA8 -2.839048   5.159019
    4   LDB2 -1.258781   4.646456
    5  PTGS1  1.009361   3.791273
    6  FABP5 -1.186742   3.189549
  

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

 volc = function(input){
  ggplot(input, aes(logFC, negLogPval))   
  geom_point()
  ggsave(paste0("Volcano_", names(input), ".png"), device = "png")
}
  

Если я запущу это в одной таблице данных, как показано ниже:

 volc(list$table1)
  

Затем он генерирует график, как и ожидалось, но вместо того, чтобы использовать имя объекта для обозначения файла, вместо этого он использует имя первого столбца в таблице данных, т. е. сохраняет файл как «Volcano_gene.png» вместо «Volcano_table1.png».

Это означает, что если я выполню это в своем списке таблиц данных, используя lapply , как показано ниже:

 lapply(list, volc)
  

Он выполняет весь код для каждой из таблиц, но сохраняет их все как «Volcano_gene.png», перезаписывая предыдущую таблицу по ходу работы, что означает, что сохраняется только самый последний сгенерированный график.

Я уверен, что мне не хватает чего-то простого в names() функции, но кто-нибудь может помочь мне исправить это, чтобы она сохраняла графики с именами, как ожидалось?

Комментарии:

1. Если вам нужны красивые графики вулканов, смотрите пакет EnhancedVolcano .

2. Проверю это, я играл с окраской своих графиков с пороговыми значениями и т.д. Вручную, я просто исключил их из примера кода. Хотя это мог бы быть более простой метод!

Ответ №1:

Вам нужны не имена столбцов data.frames в этом списке, а их имена, т.е. names(list) . Я предлагаю повторить эти имена:

 volc = function(inputname){
  ggplot(list[[inputname]], aes(logFC, negLogPval))   
  geom_point()
  ggsave(paste0("Volcano_", inputname, ".png"), device = "png")
}

for (x in names(list)) volc(x)
  

Комментарии:

1. Ах, я понимаю. names(list) применялась names() функция к отдельным таблицам данных в списке, а не к самому списку. Есть ли аналогичный способ сделать это с использованием, lapply а не for цикла? Обычно я использую, lapply поскольку предпочитаю синтаксис, но, возможно, for в данном случае это просто проще.

2. for Цикл является подходящей конструкцией, если вы вызываете функцию исключительно для побочных эффектов, как вы делаете здесь.

3. Возможно, я неправильно понимаю терминологию, но как этот пример использует ее для побочных эффектов? ggplot Вызывается для его функции построения графика, а names() вызывается для его функции предоставления имен элементов в списке. Верно? Я новичок в кодировании, поэтому, возможно, побочные эффекты имеют значение, отличное от того, к чему я привык?

4. Сохранение файлов и построение графиков являются побочными эффектами в отличие от возврата значения.

5. Хм, хорошо, это не кажется очевидным, но спасибо. Также я, наконец, попытался запустить вашу версию, чтобы проверить, работает ли она так же хорошо, как версия Map () от Tommy, но она вернулась со следующей ошибкой: Error in list[[inputname]] : object of type 'builtin' is not subsettable РЕДАКТИРОВАТЬ: неважно, я решил это сам почти сразу после публикации, я забыл переименовать «список» в мое фактическое имя списка.

Ответ №2:

Проблема с вашим кодом заключается в том, что когда вы применяете свою функцию к каждому data.frame из вашего list then names(input) , она выдает вам имена столбцов data.frame . Смотрите этот пример.

 data(mtcars)
l = list()
l$a = mtcars[, 1:2]
l$b = mtcars[, 2:3]

lapply(l, names)
$a
[1] "mpg" "cyl"

$b
[1] "cyl"  "disp"
  

Для решения этой проблемы измените функцию, чтобы она принимала второе имя аргумента.

 volc = function(input, name) {
  ggplot(input, aes(logFC, negLogPval))   
  geom_point()
  ggsave(paste0("Volcano_", name, ".png"), device = "png")
}
  

Теперь вы можете использовать Map для архивирования своей цели:

 Map(volc, list, names(list))
  

Комментарии:

1. Понятно, спасибо за помощь. Я ответил Roland до того, как прочитал это, но это лучший способ сделать это по всему списку без использования for циклов.