Rでコマンド:「XML」パッケージでxlsxファイルを読み込むコマンド例

Rの解析に役に立つ記事
スポンサーリンク

docxファイルやxlsxファイルはxlmファイル群をzipで圧縮した構造です。解凍してしまえばXMLパッケージで読み込むことができます。そこで、XMLパッケージの利用例としてxlsxファイルを読み込むコマンド例を作成しました。

XMLパッケージの利用例を目的に作成したので処理速度が遅いですが、10,000程度のデータであれば約1分以内に処理できるので、我慢できる範囲かと思います。

なお、sapplyとxpathSApplyでデータを取得している箇所を工夫すると読み込み速度が快適になると思います。ぜひ、挑戦してみてください。

パッケージを利用して快適にxlsxファイルを読み込みたい方は下記記事をどうぞ。

・openxlsxパッケージの紹介
 https://www.karada-good.net/analyticsr/r-338/

・XLConnectパッケージの紹介
 https://www.karada-good.net/analyticsr/r-51/

・WriteXLSパッケージの紹介
 https://www.karada-good.net/analyticsr/r-138/

参考にXMLパッケージで読み込むdocxファイルの例です。
 https://www.karada-good.net/analyticsr/r-368/

実行コマンドはR version 3.2.2で確認しています。

スポンサーリンク

オリジナルのxlsxとR内での表示

XMLXlsx

実行コマンド

詳細はコメント、コマンドのヘルプを確認してください。

[code language="R"]
#必要パッケージの読み込み
library("tcltk")
install.packages("XML")
library("XML")

#ファイルを選択
file <- paste0(as.character(tkgetOpenFile(title = "&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                             filetypes = '{"&#12501;&#12449;&#12452;&#12523;" {".xlsx"}}',
                                             initialfile = c("*.xlsx"))))

#&#35501;&#12415;&#36796;&#12416;&#12471;&#12540;&#12488;&#30058;&#21495;&#12434;&#35373;&#23450;
SheetId <- 1

#&#19968;&#26178;&#12501;&#12457;&#12523;&#12480;&#12434;&#20316;&#25104;
tmp <- tempfile()
#xlsx&#12501;&#12449;&#12452;&#12523;&#12434;&#35299;&#20941;
unzip(file, exdir = tmp)
#&#25991;&#23383;&#24773;&#22577;&#12398;xml&#12501;&#12449;&#12452;&#12523;&#12497;&#12473;&#12434;&#21462;&#24471;
xmlStringsPath <- file.path(tmp, "xl", "sharedStrings.xml")
#&#12471;&#12540;&#12488;&#24773;&#22577;&#12398;xml&#12501;&#12449;&#12452;&#12523;&#12497;&#12473;&#12434;&#21462;&#24471;
xmlSheetPath <- file.path(tmp, "xl", "worksheets", paste0("sheet", SheetId, ".xml"))

#&#25991;&#23383;&#24773;&#22577;&#12398;xml&#12434;&#35501;&#12415;&#36796;&#12415;
StringsData <- xmlParse(xmlStringsPath)
#&#25991;&#23383;&#24773;&#22577;&#12398;&#21462;&#24471;,namespace&#12434;&#35373;&#23450;&#12377;&#12427;&#12398;&#12364;&#12509;&#12452;&#12531;&#12488;
GetStringsData <- xpathSApply(StringsData, "//x:si", namespaces = "x", xmlValue)

#&#12471;&#12540;&#12488;&#24773;&#22577;&#12398;xml&#12434;&#35501;&#12415;&#36796;&#12415;
SheetData <- xmlParse(xmlSheetPath)
#&#21015;&#24773;&#22577;&#12434;&#21462;&#24471;,&lt;row&gt;&#12398;spans&#23646;&#24615;&#20516;&#12434;&#21462;&#24471;&#12375;&#12390;&#26368;&#22823;&#20516;&#12434;&#21462;&#24471;
GetRC <- xpathSApply(SheetData, "//x:row", namespaces = "x", xmlGetAttr, "spans")
ColRange <- unlist(strsplit(unique(GetRC), ":"))
ColRange <- type.convert(ColRange[2])
#&#21015;&#30058;&#21495;&#21462;&#24471;&#29992;&#12398;&#12450;&#12523;&#12501;&#12449;&#12505;&#12483;&#12488;&#37197;&#21015;&#12434;&#20316;&#25104;
GetColNo <- LETTERS
for(m in seq(ceiling(ColRange/26))){
  
  GetColNo <- c(GetColNo, paste0(LETTERS[m], LETTERS))
  
}

#temp&#12501;&#12457;&#12523;&#12480;&#12398;&#21066;&#38500;
unlink(tmp, recursive = TRUE)

#&#34892;&#21015;&#30058;&#21495;&#12398;&#21462;&#24471;
DataRowColNO <- sapply(list(xmlChildren(SheetData))[[1]], function(x) xpathSApply(x, "//x:c", namespaces = "x", xmlGetAttr, "r"))  
#&#34892;&#30058;&#21495;&#12398;&#21462;&#24471;
DataRowNO <- type.convert(gsub("[[:alpha:]]", "", DataRowColNO))
#&#21015;&#30058;&#21495;&#12398;&#25968;&#20516;&#21270;&#12539;&#21462;&#24471;
DataColNO <- match(gsub("[[:digit:]]", "", DataRowColNO), GetColNo)
#&#12487;&#12540;&#12479;&#23646;&#24615;&#12398;&#21462;&#24471;
DatatValue <- sapply(list(xmlChildren(SheetData))[[1]], function(x) xpathSApply(x, "//x:c", namespaces = "x", xmlGetAttr, "t"))
#&#12487;&#12540;&#12479;&#12398;&#21462;&#24471;
RawData <- type.convert(sapply(xpathSApply(SheetData, "//x:row", namespaces = "x"),
                                  function(x) xpathSApply(x, "//x:v", namespaces = "x", xmlValue))[, 1])
#&#23646;&#24615;&#12395;&#21512;&#12431;&#12379;&#12390;&#12486;&#12461;&#12473;&#12488;&#12434;&#21462;&#24471;&#12375;&#35442;&#24403;&#31623;&#25152;&#12434;&#32622;&#25563;
RawData[DatatValue == "s"] <- GetStringsData[RawData[DatatValue == "s"] + 1]
#&#12487;&#12540;&#12479;&#12434;&#32080;&#21512;
ExData <- data.frame(DataRowNO, DataColNO, I(RawData))

#ExData&#12434;&#20803;&#12395;data.frame&#12434;&#20316;&#25104;
#&#12487;&#12540;&#12479;&#26684;&#32013;&#29992;&#12398;matrix&#12434;&#20316;&#25104;
MasterMatrix <- matrix(NA, nrow = max(ExData[, 1]), ncol = max(ExData[, 2]))

for(n in seq(nrow(ExData))){
  
  MasterMatrix[ExData[n, 1], ExData[n, 2]] <- ExData[n, 3]
  
}

#&#24517;&#35201;&#12364;&#12354;&#12428;&#12400;&#12487;&#12540;&#12479;&#12398;&#25972;&#24418;
#1&#34892;&#30446;&#12434;&#21015;&#21517;&#12395;&#12377;&#12427;
#colnames(MasterMatrix) <- MasterMatrix[1, ]
#MasterMatrix <- MasterMatrix[-1, ]

#&#12487;&#12540;&#12479;&#12398;data.frame&#21270;
DataToXlsx <- as.data.frame(MasterMatrix)

#&#24517;&#35201;&#12398;&#12394;&#12356;&#12487;&#12540;&#12479;&#12434;&#21066;&#38500;
#rm(list = ls()[ls() != "DataToXlsx"])

#&#12362;&#12414;&#12369;,DataToXlsx&#12434;&#20316;&#26989;&#12487;&#12451;&#12524;&#12463;&#12488;&#12522;&#12395;csv&#12391;&#20986;&#21147;
#mac&#29992;
write.csv(DataToXlsx, "DataToXlsx.csv", quote = FALSE,
          row.names = FALSE, fileEncoding = "CP932", eol = "\r\n")
#windows&#29992;
write.csv(DataToXlsx, "DataToXlsx.csv", quote = FALSE, row.names = FALSE)

少しでも、あなたの解析が楽になりますように!!

タイトルとURLをコピーしました