Как перебрать Excel-листы с помощью readxl - PullRequest
0 голосов
/ 08 марта 2019

Я должен загрузить данные для моей магистерской работы в R-dataframe, который хранится в 74 рабочих книгах Excel. Каждая рабочая тетрадь имеет 4 рабочих листа, которые называются: животные, особенности, глаголы, глаголы. Все рабочие листы имеют одинаковые 12 переменных (время начала, слово, время окончания, идентификатор и т. Д.). Я хочу объединить каждый рабочий лист под предыдущим, поэтому итоговый фрейм данных должен иметь 12 столбцов, а количество строк зависит от того, сколько ответов дали 74 предмета. Я хочу использовать readxl-пакет tidyverse и следую этой статье: https://readxl.tidyverse.org/articles/articles/readxl-workflows.html#csv-caching-and-iterating-over-sheets. Первая проблема, с которой я сталкиваюсь, заключается в том, как прочитать все 4 листа с помощью read_excel (путь, лист = "животные", "особенности", "r_words", "глаголы"). Это работает только с первым листом, поэтому я попытался составить список со всеми именами листов (объектный лист). Это тоже не работает. И когда я пытаюсь использовать следующий код только с одним листом, следующая строка выдает ошибку: Ошибка в базовом имени (.): Ожидается символьный векторный аргумент Итак, вот часть моего кода, мы надеемся выполнить требования:

filenames <- list.files("data", pattern = '\\.xlsm',full.names = TRUE)

# indices
subfile_nos <- 1:length(filenames)

# function to read all the sheets in at once and cache to csv
read_then_csv <- function(sheet, path) {
  for (i in 1:length(filenames)){
    sheet <- excel_sheets(filenames[i])
     len.sheet <- 1:length(sheet)
    path <- read_excel(filenames[i], sheet = sheet[i]) #only reading in the first sheet
  pathbase <- path %>%
    basename() %>% #Error in basename(.) : a character vector argument expected
    tools::file_path_sans_ext()
  path %>%
    read_excel(sheet = sheet) %>% 
    write_csv(paste0(pathbase, "-", sheet, ".csv"))
  }
}

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Вы должны сделать двойной цикл или вложенную карту, например так:

library(dplyr)
library(purrr)
library(readxl)

# I suggest looking at 
?purrr::map_df

# Function to read all the sheets in at once and save as csv
read_then_csv <- function(input_filenames, output_file) {
  # Iterate over files and concatenate results
  map_df(input_filenames, function(f){
    # Iterate over sheets and concatenate results
    excel_sheets(f) %>%
      map_df(function(sh){
        read_excel(f, sh)
      })
  }) %>%
  # Write csv
  write_csv(output_file)
}

# Test function
filenames <- list.files("data", pattern = '\\.xlsm',full.names = TRUE)
read_then_csv(filenames, 'my_output.csv')
0 голосов
/ 13 марта 2019

Вы говорите ... «Я хочу объединить все рабочие листы под предыдущими» ... Сценарий ниже объединит все листы из всех файлов. Протестируйте его на КОПИИ своих данных, если она не выполняет то, что вы хотите / нуждаетесь в ней.

# load names of excel files 
files = list.files(path = "C:\\your_path_here\\", full.names = TRUE, pattern = ".xlsx")

# create function to read multiple sheets per excel file
read_excel_allsheets <- function(filename, tibble = FALSE) {
  sheets <- readxl::excel_sheets(filename)
  sapply(sheets, function(f) as.data.frame(readxl::read_excel(filename, sheet = f)), 
         simplify = FALSE)
}

# execute function for all excel files in "files"
all_data <- lapply(files, read_excel_allsheets)
...