Rスクリプトから直接Excelファイルを読み取る


95

ExcelファイルをRに直接読み込むにはどうすればよいですか?または、最初にデータをテキストファイルまたはCSVファイルにエクスポートし、そのファイルをRにインポートする必要がありますか?


@Sacha Epskamp:xlsReadWriteを使用すると、Perlをインストールする必要すらありません。
Joris Meys、2011年

1
gdataバージョン2.8.2 xlsxread.xls関数でファイルを読み取る
Ben

1
Excelからデータをテキスト形式にエクスポートすると、精度が失われる可能性があるという警告(以下の回答)を参照してください。
russellpierce 2014年

1
xlsxxlsx / xlsm / xlsのパッケージ、xlamなどについて知らない
Qbik

2
「最初にテキストファイルにエクスポートしない理由がわかりません。」これはどうですか:CSVにエクスポートすると、必要なフィールドの1つが書き込まれません。ある種のDRMのようですが、スプレッドシートを作成しなかったので、わかりません。
Nate Reed

回答:


41

はい。R wikiの関連ページを参照してください。短い答え:パッケージread.xlsからgdataほとんどの場合機能します(システムにPerlをインストールする必要がありますが、通常はMacOSとLinuxではすでに当てはまりますが、Windowsでは追加の手順を実行します(http://strawberryperl.com/を参照))。R wikiページにリストされているさまざまな警告と代替案があります。

私が直接これを行わない理由は、スプレッドシートにグリッチ(奇妙なヘッダー、複数のワークシート[一度に1つしか読み取れませんが、すべてをループすることはできますが]があるかどうかを調べることです。 、含まれるプロットなど)。しかし、単純な数値と文字データ(つまり、コンマ形式の数値、日付、ゼロ除算エラーのない数式、欠損値など)を含む整形式の長方形のスプレッドシートの場合、通常は問題ありません。このプロセスで。


6
私が個人的に遭遇したと考えるべき多くの潜在的な問題があります。カンマの付いた数字のフィールドは、Rで削除して数値に変換する必要があります。「-」の付いたフィールドはNAに再コード化する必要があります。全体的勧告は、本当にExcelであなたの数字を見て、彼らはR.へ正しく変換されていることを確認することです
ブランドンBertelsen

3
「あなたは本当にあなたの数字を見なければならない」と論じることができません...「-」フィールドの問題は何ですか?na.strings="-"問題に対処していますか?これらの問題のうちいくつが一般的で、XLConnectなどの他のツールで対処できる問題(コンマを含む数値フィールドなど)はいくつありますか?
ベンボルカー、2011年

1
そのコメントは、ベンではなくOPに向けられました。
Brandon Bertelsen、

1
関連逸話:read.xls両方のExcelファイルから非常に大きなシートを読みに成功XLConnectし、xlsx失敗した(どちらもに依存しているので、私は信じているのApache POI
マット・パーカー

49

@Chaseの推奨事項を繰り返します。XLConnectを使用します

XLConnectを使用する理由は、私の意見では次のとおりです。

  1. クロスプラットフォーム。XLConnectはJavaで記述されているため、Win、Linux、MacでRコードを変更せずに実行できます(パス文字列を除く)
  2. ロードするものは他にありません。XLConnectをインストールするだけで、すぐに利用できます。
  3. Excelファイルの読み取りについてのみ説明しましたが、XLConnectはセルのフォーマットの変更を含むExcelファイルも書き込みます。これは、Winだけでなく、LinuxまたはMacからも実行できます。

XLConnectは他のソリューションに比べて少し新しいので、ブログの投稿やリファレンスドキュメントであまり言及されていません。私にとってそれはとても役に立ちました。


48

そして今、readxlがあります

readxlパッケージを使用すると、ExcelからRにデータを簡単に取得できます。既存のパッケージ(gdata、xlsx、xlsReadWriteなど)と比較して、readxlには外部の依存関係がないため、すべてのオペレーティングシステムに簡単にインストールして使用できます。1つのシートに保存されている表形式のデータを操作するように設計されています。

readxlは、基礎となるバイナリ形式の複雑さの多くを抽象化するlibxls Cライブラリの上に構築されています。

従来の.xls形式と.xlsxの両方をサポートしています

readxlはCRANから入手できます。または、githubから次のようにインストールできます。

# install.packages("devtools")
devtools::install_github("hadley/readxl")

使用法

library(readxl)

# read_excel reads both xls and xlsx files
read_excel("my-old-spreadsheet.xls")
read_excel("my-new-spreadsheet.xlsx")

# Specify sheet with a number or name
read_excel("my-spreadsheet.xls", sheet = "data")
read_excel("my-spreadsheet.xls", sheet = 2)

# If NAs are represented by something other than blank cells,
# set the na argument
read_excel("my-spreadsheet.xls", na = "NA")

説明は「外部依存関係」と言っていないが、それは必要ないことに注意してくださいRcppパッケージされ、順番に(Windowsの場合)Rtoolsまたは(OSX用)のXcodeが必要で、ある多くの人々は彼らが他の理由のためにインストールされているR.けれども外部の依存関係。


3
xlsxよりもはるかに高速です。読み取り時間はread.xlsx2に似ていますが、型を推測します。
スティーブロウ

1
@SteveRoweは、これを確認するいくつかの(試行された)客観的ベンチマークの新しい回答を参照
MichaelChirico

文字列を因子として読み取る方法はありread_excelますか?と比較して速度が好きですが、read.xlsx手動で列を文字から文字に変換する必要があるため、目的が達成されません。
coip '20

2
依存関係がないという事実のための+1。私はjavaをインストールしなければならないのが嫌いです。そして私はそれを試しました、そしてそれは私にとって非常にうまくいきます。
Bastian

2
readxlとopenxlsxが最適です。readxlは高速ですが、書き込みはできません。とにかく、列のクラス/タイプを指定しようとしても、どれもうまく機能しません。
skan

29

2015年10月の編集:他の人がここでコメントしているように、openxlsxおよびreadxlパッケージはxlsxパッケージよりもはるかに高速で、実際には大きなExcelファイル(> 1500行&> 120列)を開くことができます。@MichaelChirico readxlは、速度が優先openxlsxされ、xlsxパッケージによって提供される機能を置き換える場合に、より優れていることを示しています。2015年にExcelファイルの読み取り、書き込み、変更を行うパッケージを探している場合は、openxlsxではなくを選択してくださいxlsx

2015年より前:私はxlsxパッケージを使用しました。ExcelとRを使用してワークフローを変更しました。Excelシートを.txt形式で保存するかどうかを確認するのに迷惑なポップアップが表示されることはありません。パッケージはExcelファイルも書き込みます。

ただし、read.xlsx大きなExcelファイルを開くと、機能が遅くなります。read.xlsx2関数はかなり高速ですが、data.frame列のベクタークラスをクエリしません。関数colClassesを使用read.xlsx2する場合は、コマンドを使用して必要な列クラスを指定する必要があります。ここに実用的な例があります:

read.xlsx("filename.xlsx", 1)ファイルを読み取り、data.frame列クラスをほぼ有用にしますが、大きなデータセットの場合は非常に遅くなります。.xlsファイルにも使用できます。

read.xlsx2("filename.xlsx", 1)より高速ですが、列クラスを手動で定義する必要があります。ショートカットは、コマンドを2回実行することです(以下の例を参照)。character仕様は、列を因子に変換します。時間の使用DatePOSIXctオプション。

coln <- function(x){y <- rbind(seq(1,ncol(x))); colnames(y) <- colnames(x)
rownames(y) <- "col.number"; return(y)} # A function to see column numbers

data <- read.xlsx2("filename.xlsx", 1) # Open the file 

coln(data)    # Check the column numbers you want to have as factors

x <- 3 # Say you want columns 1-3 as factors, the rest numeric

data <- read.xlsx2("filename.xlsx", 1, colClasses= c(rep("character", x),
rep("numeric", ncol(data)-x+1)))

25

Excelファイルを読み取るさまざまな方法の急増とRここでの答えの多さを考えると、ここで言及されているオプションのどれが(いくつかの単純な状況で)最高のパフォーマンスを発揮するかを明らかにしたいと思いました。

私自身xlsx、を使い始めて以来R、慣れとして他に何も使用していませんでしたが、最近、どのパッケージの方が優れているかについての客観的な情報がないようです。

一部のパッケージは特定の状況を他の状況よりも適切に処理し、他の警告の滝になるため、ベンチマークの練習は困難を伴います。

そうは言っても、かなり一般的な形式(8つの文字列フィールド、3つの数値、1つの整数、3つの日付)であると思われる(再現可能な)データセットを使用しています。

set.seed(51423)
data.frame(
  str1 = sample(sprintf("%010d", 1:NN)), #ID field 1
  str2 = sample(sprintf("%09d", 1:NN)),  #ID field 2
  #varying length string field--think names/addresses, etc.
  str3 = 
    replicate(NN, paste0(sample(LETTERS, sample(10:30, 1L), TRUE),
                         collapse = "")),
  #factor-like string field with 50 "levels"
  str4 = sprintf("%05d", sample(sample(1e5, 50L), NN, TRUE)),
  #factor-like string field with 17 levels, varying length
  str5 = 
    sample(replicate(17L, paste0(sample(LETTERS, sample(15:25, 1L), TRUE),
                                 collapse = "")), NN, TRUE),
  #lognormally distributed numeric
  num1 = round(exp(rnorm(NN, mean = 6.5, sd = 1.5)), 2L),
  #3 binary strings
  str6 = sample(c("Y","N"), NN, TRUE),
  str7 = sample(c("M","F"), NN, TRUE),
  str8 = sample(c("B","W"), NN, TRUE),
  #right-skewed integer
  int1 = ceiling(rexp(NN)),
  #dates by month
  dat1 = 
    sample(seq(from = as.Date("2005-12-31"), 
               to = as.Date("2015-12-31"), by = "month"),
           NN, TRUE),
  dat2 = 
    sample(seq(from = as.Date("2005-12-31"), 
               to = as.Date("2015-12-31"), by = "month"),
           NN, TRUE),
  num2 = round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L),
  #date by day
  dat3 = 
    sample(seq(from = as.Date("2015-06-01"), 
               to = as.Date("2015-07-15"), by = "day"),
           NN, TRUE),
  #lognormal numeric that can be positive or negative
  num3 = 
    (-1) ^ sample(2, NN, TRUE) * round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L)
)

私は、CSVファイルにこれを書いて、LibreOfficeの中で開かれたとの.xlsxファイルとして保存され、その後、パッケージの4は、このスレッドで言及したベンチマーク:xlsxopenxlsxreadxl、とgdata、デフォルトのオプションを使用して(私もかどうか、私のバージョンを試してみました列タイプを指定しますが、これはランキングを変更しませんでした)。

RODBCLinuxを使用しているため、除外します。XLConnectその主な目的は単一のExcelシートで読み取るのではなく、Excelブック全体をインポートすることであると思われるため、その読み取り能力のみを競い合うのは不公平に思えます。そしてxlsReadWrite、それはもはや私のバージョンと互換性があるので、R(と、段階的に廃止されているようです)。

次に、NN=1000LおよびNN=25000Ldata.frame上記の各宣言の前にシードをリセットして)ベンチマークを実行し、Excelファイルサイズの違いを考慮しました。gcは主にのためのものでxlsx、メモリの目詰まりを引き起こす可能性があることを発見しました。さらに苦労せずに、私が見つけた結果は次のとおりです。

1,000行のExcelファイル

benchmark1k <-
  microbenchmark(times = 100L,
                 xlsx = {xlsx::read.xlsx2(fl, sheetIndex=1); invisible(gc())},
                 openxlsx = {openxlsx::read.xlsx(fl); invisible(gc())},
                 readxl = {readxl::read_excel(fl); invisible(gc())},
                 gdata = {gdata::read.xls(fl); invisible(gc())})

# Unit: milliseconds
#      expr       min        lq      mean    median        uq       max neval
#      xlsx  194.1958  199.2662  214.1512  201.9063  212.7563  354.0327   100
#  openxlsx  142.2074  142.9028  151.9127  143.7239  148.0940  255.0124   100
#    readxl  122.0238  122.8448  132.4021  123.6964  130.2881  214.5138   100
#     gdata 2004.4745 2042.0732 2087.8724 2062.5259 2116.7795 2425.6345   100

そうreadxlで勝者であり、openxlsx競争力とgdata明確な敗者は。列の最小値を基準にして各測定を行います。

#       expr   min    lq  mean median    uq   max
# 1     xlsx  1.59  1.62  1.62   1.63  1.63  1.65
# 2 openxlsx  1.17  1.16  1.15   1.16  1.14  1.19
# 3   readxl  1.00  1.00  1.00   1.00  1.00  1.00
# 4    gdata 16.43 16.62 15.77  16.67 16.25 11.31

私のお気に入りは、にxlsx比べて60%遅いですreadxl

25,000行のExcelファイル

時間がかかるため、大きなファイルで繰り返したのは20回だけでしたが、それ以外はコマンドは同じでした。これが生データです:

# Unit: milliseconds
#      expr        min         lq       mean     median         uq        max neval
#      xlsx  4451.9553  4539.4599  4738.6366  4762.1768  4941.2331  5091.0057    20
#  openxlsx   962.1579   981.0613   988.5006   986.1091   992.6017  1040.4158    20
#    readxl   341.0006   344.8904   347.0779   346.4518   348.9273   360.1808    20
#     gdata 43860.4013 44375.6340 44848.7797 44991.2208 45251.4441 45652.0826    20

相対データは次のとおりです。

#       expr    min     lq   mean median     uq    max
# 1     xlsx  13.06  13.16  13.65  13.75  14.16  14.13
# 2 openxlsx   2.82   2.84   2.85   2.85   2.84   2.89
# 3   readxl   1.00   1.00   1.00   1.00   1.00   1.00
# 4    gdata 128.62 128.67 129.22 129.86 129.69 126.75

だから、readxlそれはスピードになると明確な勝者です。gdataExcelファイルの読み込みが非常に遅く、この問題はより大きなテーブルでのみ悪化するため、別の方法で解決することをお勧めします。

二つはの描くopenxlsxその豊富な他の方法は、(1)あるreadxl行うように設計されただけで、おそらくそれは非常に高速である理由の一部)、特にそのある一つのこと、write.xlsxより多くのための欠点の機能、および2)( readxlcol_types内の引数readxl(としてのみをこの執筆の)いくつかの非標準を受け入れますR:の"text"代わりに"character"およびの"date"代わりに"Date"


XLConnectのベンチマークも追加するとよいでしょう。また、readxlで書き込みできないこともコメントしてください。xlsxおよびopenxlsxは、col_typesオプションまたはcolClassesオプションでは正しく機能しません。
スカン

@skan私は最初にいくつかのテストを実行しましたXLConnectが、非常に遅いです。私は信じているreadxlの欠点は十分に私の最後の段落で覆われていました。そして私はとのあなたにノー似たような経験を持っていますxlsxか、openxlsx私は定期的に型を指定するために両方を使用するようにします。
MichaelChirico


13
library(RODBC)
file.name <- "file.xls"
sheet.name <- "Sheet Name"

## Connect to Excel File Pull and Format Data
excel.connect <- odbcConnectExcel(file.name)
dat <- sqlFetch(excel.connect, sheet.name, na.strings=c("","-"))
odbcClose(excel.connect)

個人的には、RODBCが好きで、お勧めできます。


7
警告:ODBCは、Windows以外のプラットフォームで実行するのが難しい場合があります。
JD Long、

1
@JD長く、WindowsでもPITAです。64ビットW7で私とODBCにセクシーな時間はありません...
RomanLuštrikAug

4
必要なパッケージのロード:odbcConnectExcel(file.name)のRODBCエラー:odbcConnectExcelは32ビットWindowsでのみ使用可能
andrekos


6

別の解決策はxlsReadWriteパッケージです。追加のインストールは必要ありませんが、次の方法で初めて使用する前に追加のshlibをダウンロードする必要があります。

require(xlsReadWrite)
xls.getshlib()

これを忘れると、完全なフラストレーションを引き起こす可能性があります。そこにいたことすべて...

補足:テキストベースの形式(csvなど)に変換してそこから読み込むことを検討することもできます。これにはいくつかの理由があります:

  • ソリューション(RODBC、gdata、xlsReadWrite)が何であれ、データが変換されると奇妙なことが起こります。特に日付はかなり扱いにくい場合があります。HFWutilsパッケージは、(@Ben Bolkerさんのコメントあたり)EXCELの日付に対処するためのいくつかのツールを持っています。

  • 大きなシートがある場合、テキストファイルでの読み取りは、EXCELからの読み取りよりも高速です。

  • .xlsおよび.xlsxファイルの場合、異なるソリューションが必要になる場合があります。EG xlsReadWriteパッケージは現在、.xlsx AFAIKをサポートしていません。gdata.xlsxをサポートするには、追加のperlライブラリをインストールする必要があります。xlsxパッケージは同じ名前の拡張機能を処理できます。


ヒントは@Ben Thxです。回答に含めます。しかし、受け入れられた回答へのリンクへのWikiページはすでにかなり完成しているので、完成しようとはしませんでした。ただし、HFWutilsパッケージについては触れられていません。
Joris Meys、2011年

1
-1; 私の答えを見てください。TL:DR:Excelは完全な精度のデータセットをcsv(またはクリップボード)に保存しません。表示されている値のみが保持されます。
russellpierce 2014年

5

上記の他の回答の多くで述べたように、XLS / Xファイルに接続して適切な方法でデータを取得する優れたパッケージが数多くあります。ただし、どのような状況でもクリップボード(または.csv)ファイルを使用してExcelからデータを取得するべきではないことを警告する必要があります。理由を確認する=1/3には、Excelのセルに入力してください。次に、表示される小数点の数を2に減らします。次に、データをコピーしてRに貼り付けます。CSVを保存します。どちらの場合も、Excelはインターフェイスを通じて表示されたデータのみを有効に保持しており、実際のソースデータの精度がすべて失われていることに気付くでしょう。


1
私は、数値の忠実度が関連性/重要性がないと誰が思ったのか知りたいです。
russellpierce 2015

1
良い警告です。ただし、使用するパッケージによって異なります。一部はこのトラップに陥っていません。
RockScience 16

@RocketScienceこれは、ExcelによるCSVエクスポートでの基本的な設計選択です。この問題のないクリップボードを使用するパッケージの例はありますか?xls xlsxファイルを直接解析するパッケージは、このトラップに該当しない傾向があります。したがって、私の警告の具体的な範囲。
russellpierce 2016

Unixでは、試すことができますgnumeric::read.gnumeric.sheet。Windowsでは100%確実ではありませんが、gdata::read.xlsうまく機能するはずです(ただしperlをインストールする必要があります)
RockScience

@RockScience敬具、gdata :: read.xlsはクリップボードデータを操作しません(邪魔にならない限り)。gnumericはExcelではありません。だから、特別な証拠がなければ、私の警告は立っています。この質問への回答には、他にも多くの優れた選択肢があります。人々が代わりにそれらを使用することを期待しましょう。
russellpierce 2016

5

@Mikkoが提供する答えを拡張すると、列のクラスを事前に「知る」必要なく、巧妙なトリックを使用して処理を高速化できます。read.xlsx限られた数のレコードを取得してクラスを決定し、それをフォローアップするだけで使用できますread.xlsx2

# just the first 50 rows should do...
df.temp <- read.xlsx("filename.xlsx", 1, startRow=1, endRow=50) 
df.real <- read.xlsx2("filename.xlsx", 1, 
                      colClasses=as.vector(sapply(df.temp, mode)))

1
あなたのソリューションは返すnumericためにfactors私のコンピュータ上で。関数でをread.xlsx使用characterしてreadColumns因子を指定します。因子を文字として取得するよりエレガントな方法があると確信していますが、機能する関数の変更バージョンを次に示しますdf.real <- read.xlsx2("filename.xlsx", 1, colClasses=gsub("factor", "character", as.vector(sapply(df.temp, class))))
ミッコ、

これは、列タイプが最初の行によって適切に決定できる範囲でのみ機能します。通常、最初の行より多くを解析して、その決定を行います。これらの関数のソースであるパッケージに名前を付けることで、aaa90210のコメントに対処するように回答を改善できます。
russellpierce 2017

1

Excelファイルは、次のようにRに直接読み込むことができます。

my_data <- read.table(file = "xxxxxx.xls", sep = "\t", header=TRUE)

readxlパッケージを使用してxlsおよびxlxsファイルを読み取る

library("readxl")
my_data <- read_excel("xxxxx.xls")
my_data <- read_excel("xxxxx.xlsx")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.