Применить функцию к строкам фрейма данных, вернуть список фреймов данных - PullRequest
0 голосов
/ 05 мая 2020

Я читаю несколько книг Excel, которые имеют разные диапазоны для чтения и потенциально находятся на разных листах внутри каждой книги. Я использую главный файл, который содержит имя файла, имя, которое я хочу назвать данными, диапазон для чтения и лист (если это не лист 1). Это мой главный файл:

Files = structure(list(file = c("Alaska.xls", "Analysis of Y-chromosome STRs in Chile.xlsx", 
"Bolivia.xlsx", "carribean.xlsx", "Chachapoya.xlsx", "Colombian.XLSX", 
"ndigenous Maya population from Guatemala.xlsx", "Nicaragua Nunez.xls", 
"Nicaragua.xls", "Palha Brazil.xls", "Patagonia.xls", "Promega Y23 Haplotypes Jun2019.xlsx", 
"Roewer et al.XLS", "Rio de Janeiro.xls", "The geographic mosaic of Ecuadorian.xlsx", 
"Xu2015Data-original.xlsx"), name = c("Alaska", "Chile", "Bolivia", 
"Carribean", "Chachapoya", "Colombian", "Guatemala", "Nicaragua", 
"Nicaragua", "Palha", "Patagonia", "Promega", "Roewer", "Rio", 
"Ecuador", "Xu"), range = c("G3:X31", "E3:U981", "I4:X230", "C4:S611", 
"C2:Y185", "I3:Q80", "D1:S101", "B1:R165", "AQ2:BF167", "G2:AB2534", 
"B8:J108", "C2:AT226", "J1:Y1012", "B3:Q608", "G4:AB419", "C2:S981"
), sheet = c("Table S8 Y chromosome STRs", "", "", "", "", "", 
"", "", "", "", "", "", "", "", "", "")), class = "data.frame", row.names = c(NA, 
-16L))

И он выглядит так:

> Files
                                            file       name     range                      sheet
1                                     Alaska.xls     Alaska    G3:X31 Table S8 Y chromosome STRs
2    Analysis of Y-chromosome STRs in Chile.xlsx      Chile   E3:U981                           
3                                   Bolivia.xlsx    Bolivia   I4:X230                           
4                                 carribean.xlsx  Carribean   C4:S611                           
5                                Chachapoya.xlsx Chachapoya   C2:Y185                           
6                                 Colombian.XLSX  Colombian    I3:Q80                           
7  ndigenous Maya population from Guatemala.xlsx  Guatemala   D1:S101                           
8                            Nicaragua Nunez.xls  Nicaragua   B1:R165                           
9                                  Nicaragua.xls  Nicaragua AQ2:BF167                           
10                              Palha Brazil.xls      Palha G2:AB2534                           
11                                 Patagonia.xls  Patagonia   B8:J108                           
12           Promega Y23 Haplotypes Jun2019.xlsx    Promega  C2:AT226                           
13                              Roewer et al.XLS     Roewer  J1:Y1012                           
14                            Rio de Janeiro.xls        Rio   B3:Q608                           
15      The geographic mosaic of Ecuadorian.xlsx    Ecuador  G4:AB419                           
16                      Xu2015Data-original.xlsx         Xu   C2:S981        

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

Я пробовал использовать только apply, что некрасиво и не работает:

readFiles = function(){
  Files = read.csv(system.file("extdata", "files.csv", package = "purps"))

  Sheets = vector(mode = "list", length = length(Files$File))
  names(Sheets) = Files$Name

  readFile = function(row){
    row = as.list(row)
    path = system.file("extdata", file, package = "purps")
    read_excel(path, range = row$range, sheet = ifelse(row$sheet == "", NULL, row$sheet))
  }

  Sheets = apply(Files, 1, readFile)

  return(Sheets)
}
> readFiles()
 Error in file.path(packagePath, ...) : 
  cannot coerce type 'closure' to vector of type 'character' 

Я уверен, что есть элегантное решение, использующее purrr или что-то еще, о чем я не знаю! Я также уверен, что мог бы просто сделать это с помощью al oop, но должен быть более компактный способ.

1 Ответ

1 голос
/ 05 мая 2020

Вы можете попытаться разделить каждую строку в Files как список фреймов данных, а затем передать их функции readFiles.

readFiles = function(row){
   path = system.file("extdata", file, package = "purps")
   data <- readxl::read_excel(path, range = row$range, 
                   sheet = ifelse(row$sheet == "", NULL, row$sheet))
   return(data)
}

list_data <- lapply(split(Files, seq(nrow(Files))), readFiles)

Чтобы назвать список, вы можете сделать:

names(list_data) <- Files$name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...