potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

R&tidyverse&openxlsx xlsxファイルのテーブルを読み込む

xlsxファイルでテーブルの名前からデータを読み込むコードです。テーブルの名前からシート名とA1形式範囲の取得はopenxlsx、シート名とA1形式範囲の読み込みにはreadxlを使用しています。

カレントディレクトリに「テーブル1」テーブルを持つxlsxファイルを作成してから実行してください。

library(openxlsx)
library(stringr)
library(tibble)
library(readxl)
library(dplyr)

getXlsxSheetAndRangeByTableName <- function(file, table.name, xlsxFile=NULL, isUnzipped=FALSE)
{
  #「Invalid multibyte string」エラーで失敗する場合はコメント解除してください。
  #Sys.setlocale("LC_ALL", "English")
  wb <- openxlsx::loadWorkbook(file, xlsxFile, isUnzipped)
  re <- stringr::fixed(table.name, ignore_case=TRUE)
  for (sheet.name in openxlsx::getSheetNames(file))
  {
    table.namerefs <- enframe(openxlsx::getTables(wb, sheet.name), name="range", value="name")
    table.nameref <- table.namerefs %>% filter(stringr::str_detect(name, re))
    if (nrow(table.nameref) != 0)
    {
      return(list(sheet.name=sheet.name, range=table.nameref$range))
    }
  }
  return(NULL)
}

loadXlsxTableByName <- function(file, table.name, xlsxFile=NULL, isUnzipped=FALSE, ...)
{
  table.nameref <- getXlsxSheetAndRangeByTableName(file, table.name, xlsxFile, isUnzipped)
  if (is.null(table.nameref))
  {
    return(NULL)
  }
  return(readxl::read_xlsx(file, sheet=table.nameref$sheet, range=table.nameref$range, ...))
}

getSheetAndRangeByTableName("sample.xlsx", "テーブル1")
loadXlsxTableByName("sample.xlsx", "テーブル1")