将文件名和 sheet 名称分配给 R 中的(多个)观察值
Assigning the filename and sheet name to (multiple) observations in R
我写了一个函数,在给出文件夹的方向后,获取其中的所有 excel 文件,并通过一些适度的修改将它们合并到一个数据框中。
但是我有两件小事想补充但很难解决:
- 每个文件的名称中都有一个国家代码,我希望该函数在数据框中创建一个额外的列,"Country",其中每个观察值都将分配这样的国家代码。 名称示例:BGR_CO2_May12
- 每个文件由许多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))
我写了一个函数,在给出文件夹的方向后,获取其中的所有 excel 文件,并通过一些适度的修改将它们合并到一个数据框中。
但是我有两件小事想补充但很难解决:
- 每个文件的名称中都有一个国家代码,我希望该函数在数据框中创建一个额外的列,"Country",其中每个观察值都将分配这样的国家代码。 名称示例:BGR_CO2_May12
- 每个文件由许多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))