将文件名和 sheet 名称分配给 R 中的(多个)观察值

Assigning the filename and sheet name to (multiple) observations in R

我写了一个函数,在给出文件夹的方向后,获取其中的所有 excel 文件,并通过一些适度的修改将它们合并到一个数据框中。

但是我有两件小事想补充但很难解决:

  1. 每个文件的名称中都有一个国家代码,我希望该函数在数据框中创建一个额外的列,"Country",其中每个观察值都将分配这样的国家代码。 名称示例:BGR_CO2_May12
  2. 每个文件由许多sheet组成,每个sheet代表年份;这些 sheet 也被这些年称为。我想要创建另一列 "Year" 的函数,其中每个观察值都将分配给它来自的 sheet 的名称。

有什么好的方法吗?可能不修改当前函数?

multmerge_xls_TEST <- function(mypath2) {

library(dplyr)
library(readxl)
library(XLConnect)
library(XLConnectJars)
library(stringr)

# This function gets the list of files in a given folder

re_file <- ".+\.xls.?"
testFiles <- list.files(path       = mypath2, 
                        pattern    = re_file, 
                        full.names = TRUE)

# This function rbinds in a single dataframe the content of multiple sheets in the same workbook 
# (assuming that all the sheets have the same column types)
# It also removes the first sheet (no data there)

rbindAllSheets <- function(file) {
    wb <- loadWorkbook(file)
    removeSheet(wb, sheet = 1)
    sheets <- getSheets(wb)
    do.call(rbind,
            lapply(sheets, function(sheet) {
                           readWorksheet(wb, sheet)
            })
    )
}

# Getting a single dataframe for all the Excel files and cutting out the unnecessary variables

result <- do.call(rbind, lapply(testFiles, rbindAllSheets))
result <- result[,c(1,2,31)]

尝试围绕 readWorksheet() 制作一个包装器。这会将文件名存储到变量 Country 中,将 sheet 名称存储到 Year 中。不过,您需要对文件执行一些正则表达式才能仅获取代码。

您也可以跳过包装器,只需在当前函数中添加 mutate() 行。请注意,这使用了您已经引用的 dplyr 包。

read_worksheet <- function(sheet, wb, file) {

  readWorksheet(wb, sheet) %>%
    mutate(Country = file,
           Year = sheet)

}

那么你可以在你已有的函数中做这样的事情。

rbindAllSheets <- function(file) {
    wb <- loadWorkbook(file)
    removeSheet(wb, sheet = 1)
    sheets <- getSheets(wb)
    do.call(rbind,
            lapply(sheets, read_worksheet, wb = wb, file = file)
    )
}

另外请注意,bind_rows() 是另一个 dplyr 函数,可以代替您的 do.call(rbind, ...) 调用。

bind_rows(lapply(sheets, read_worksheet, wb = wb, file = file))