Baca file Excel langsung dari skrip R.

95

Bagaimana saya bisa membaca file Excel langsung ke R? Atau haruskah saya mengekspor dulu data ke file teks atau CSV dan mengimpor file itu ke R?

waanders
sumber
@Sacha Epskamp: dengan xlsReadWrite, Anda bahkan tidak perlu menginstal Perl.
Joris Meys
1
gdataversi 2.8.2 membaca xlsxfile dengan read.xlsfungsi
Ben
1
Lihat peringatan saya (sebagai jawaban di bawah) mengenai kemungkinan hilangnya presisi jika Anda mengekspor data ke format teks dari Excel.
russellpierce
1
xlsxpaket untuk xlsx / xlsm / xls, tidak tahu tentang xlam dll.
Qbik
2
"Saya tidak pernah melihat alasan untuk tidak mengekspor ke file teks terlebih dahulu". Bagaimana dengan ini: Saat saya mengekspor ke CSV, salah satu kolom yang saya butuhkan tidak ditulis. Sepertinya semacam DRM tetapi karena saya tidak menulis spreadsheet, saya tidak tahu.
Nate Reed

Jawaban:

41

Iya. Lihat halaman yang relevan di R wiki . Jawaban singkat: read.xlsdari gdatapaket bekerja hampir sepanjang waktu (meskipun Anda perlu menginstal Perl di sistem Anda - biasanya sudah benar di MacOS dan Linux, tetapi mengambil langkah ekstra di Windows, yaitu lihat http://strawberryperl.com/ ). Ada berbagai peringatan, dan alternatif, yang terdaftar di halaman R wiki.

Satu-satunya alasan saya tidak melakukan ini secara langsung adalah karena Anda mungkin ingin memeriksa spreadsheet untuk melihat apakah ada gangguan (header aneh, beberapa lembar kerja [Anda hanya dapat membaca satu per satu, meskipun Anda jelas dapat mengulang semuanya] , termasuk plot, dll.). Tetapi untuk spreadsheet persegi panjang yang dibentuk dengan baik dengan data angka dan karakter biasa (yaitu, bukan angka yang diformat koma, tanggal, rumus dengan kesalahan bagi-dengan-nol, nilai yang hilang, dll. ..) Saya biasanya tidak memiliki masalah dengan proses ini.

Ben Bolker
sumber
6
Ada banyak potensi masalah untuk dipertimbangkan yang saya alami secara pribadi. Bidang dengan angka dengan koma perlu dihilangkan dan diubah menjadi numerik dalam R. Bidang dengan "-" perlu dikodekan ulang ke NA. Rekomendasi keseluruhan adalah untuk benar-benar melihat nomor Anda di Excel dan memastikan bahwa mereka diterjemahkan dengan benar ke dalam R.
Brandon Bertelsen
3
Tidak bisa berdebat dengan "Anda benar-benar perlu melihat nomor Anda" ... apa masalah dengan bidang "-"? tidak na.strings="-"mengatasi masalah? Berapa banyak dari masalah ini yang umum dan berapa banyak di antaranya (misalnya bidang numerik dengan koma) yang dapat diatasi dengan alat lain seperti XLConnect ...?
Ben Bolker
1
Komentar itu ditujukan kepada OP, bukan pada Anda Ben, salah saya karena penempatan yang buruk.
Brandon Bertelsen
1
Anekdot yang relevan: read.xlsberhasil membaca lembar yang sangat besar dari file Excel di mana keduanya XLConnectdan xlsxgagal (saya percaya karena mereka berdua mengandalkan Apache POI )
Matt Parker
49

Izinkan saya mengulangi apa yang direkomendasikan @Chase: Gunakan XLConnect .

Alasan menggunakan XLConnect, menurut saya:

  1. Lintas platform. XLConnect ditulis di Java dan, dengan demikian, akan berjalan di Win, Linux, Mac tanpa perubahan kode R Anda (kecuali mungkin string jalur)
  2. Tidak ada lagi untuk dimuat. Cukup instal XLConnect dan lanjutkan hidup.
  3. Anda hanya menyebutkan membaca file Excel, tetapi XLConnect juga akan menulis file Excel, termasuk mengubah format sel. Dan itu akan melakukan ini dari Linux atau Mac, bukan hanya Win.

XLConnect agak baru dibandingkan dengan solusi lain sehingga lebih jarang disebutkan dalam posting blog dan dokumen referensi. Bagi saya ini sangat berguna.

JD Long
sumber
48

Dan sekarang ada readxl :

Paket readxl memudahkan untuk mendapatkan data dari Excel dan ke R. Dibandingkan dengan paket yang ada (mis. Gdata, xlsx, xlsReadWrite dll) readxl tidak memiliki dependensi eksternal sehingga mudah untuk diinstal dan digunakan di semua sistem operasi. Ini dirancang untuk bekerja dengan data tabel yang disimpan dalam satu lembar.

readxl dibangun di atas pustaka libxls C, yang mengabstraksi banyak kerumitan format biner yang mendasarinya.

Ini mendukung format .xls lama dan .xlsx

readxl tersedia dari CRAN, atau Anda dapat menginstalnya dari github dengan:

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

Pemakaian

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")

Perhatikan bahwa sementara deskripsi mengatakan 'tidak ada ketergantungan eksternal', itu memang memerlukan Rcpppaket , yang pada gilirannya membutuhkan Rtools (untuk Windows) atau Xcode (untuk OSX), yang merupakan dependensi di luar R. Meskipun banyak orang menginstalnya karena alasan lain .

Ben
sumber
3
Jauh lebih cepat dari xlsx. Waktu baca seperti read.xlsx2, tetapi menyimpulkan jenisnya.
Steve Rowe
1
@SteveRowe melihat jawaban baru untuk beberapa (percobaan) tolok ukur obyektif yang mengkonfirmasikan ini
MichaelChirico
Apakah ada cara untuk membaca string sebagai penggunaan faktor read_excel? Saya suka kecepatannya dibandingkan read.xlsx, tetapi harus mengonversi kolom secara manual dari karakter menjadi faktor mengalahkan tujuannya.
coip
2
1 untuk fakta bahwa ia tidak memiliki ketergantungan. Saya benci harus menginstal java. Dan saya telah mencobanya dan hasilnya sangat baik bagi saya.
Bastian
2
readxl dan openxlsx adalah yang terbaik. readxl lebih cepat tetapi tidak memungkinkan untuk menulis. Bagaimanapun, tidak ada yang berfungsi dengan baik saat mencoba menentukan kelas / jenis kolom.
skan
29

EDIT 2015-Oktober: Seperti yang dikomentari orang lain di sini, paket openxlsxdan readxljauh lebih cepat daripada xlsxpaket dan benar-benar berhasil membuka file Excel yang lebih besar (> 1500 baris &> 120 kolom). @MichaelChirico mendemonstrasikan yang readxllebih baik ketika kecepatan lebih disukai dan openxlsxmenggantikan fungsionalitas yang disediakan oleh xlsxpaket. Jika Anda mencari paket untuk membaca, menulis, dan memodifikasi file Excel pada tahun 2015, pilih sebagai openxlsxganti xlsx.

Pra-2015: Saya telah menggunakan xlsxpaket . Ini mengubah alur kerja saya dengan Excel dan R. Tidak ada lagi pop-up yang bertanya, jika saya yakin ingin menyimpan lembar Excel saya dalam format .txt. Paket ini juga menulis file Excel.

Namun, saya menemukan read.xlsxfungsinya lambat, saat membuka file Excel yang besar. read.xlsx2fungsi jauh lebih cepat, tetapi tidak menghentikan kelas vektor kolom data.frame. Anda harus menggunakan colClassesperintah untuk menentukan kelas kolom yang diinginkan, jika Anda menggunakan read.xlsx2fungsi. Berikut contoh praktisnya:

read.xlsx("filename.xlsx", 1)membaca file Anda dan membuat kelas kolom data.frame hampir berguna, tetapi sangat lambat untuk kumpulan data yang besar. Bekerja juga untuk .xlsfile.

read.xlsx2("filename.xlsx", 1)lebih cepat, tetapi Anda harus menentukan kelas kolom secara manual. Jalan pintasnya adalah dengan menjalankan perintah dua kali (lihat contoh di bawah). characterspesifikasi mengubah kolom Anda menjadi faktor. Gunakan Datedan POSIXctopsi untuk waktu.

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)))
Mikko
sumber
25

Mengingat semakin banyaknya cara berbeda untuk membaca file Excel Rdan banyaknya jawaban di sini, saya pikir saya akan mencoba menjelaskan beberapa opsi yang disebutkan di sini yang berkinerja terbaik (dalam beberapa situasi sederhana).

Saya sendiri telah menggunakan xlsxsejak saya mulai menggunakan R, untuk inersia jika tidak ada yang lain, dan saya baru-baru ini menyadari bahwa sepertinya tidak ada informasi objektif tentang paket mana yang bekerja lebih baik.

Setiap latihan pembandingan penuh dengan kesulitan karena beberapa paket pasti menangani situasi tertentu lebih baik daripada yang lain, dan air terjun peringatan lainnya.

Karena itu, saya menggunakan kumpulan data (yang dapat direproduksi) yang menurut saya dalam format yang cukup umum (8 bidang string, 3 angka, 1 bilangan bulat, 3 tanggal):

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)
)

Saya kemudian menulis ini untuk csv dan dibuka di LibreOffice dan disimpan sebagai file .xlsx, maka mengacu 4 paket yang disebutkan di thread ini: xlsx, openxlsx, readxl, dan gdata, menggunakan pilihan default (Saya juga mencoba versi apakah saya tentukan jenis kolom, tetapi ini tidak mengubah peringkat).

Saya tidak termasuk RODBCkarena saya menggunakan Linux; XLConnectkarena tampaknya tujuan utamanya bukanlah membaca dalam satu lembar Excel tetapi mengimpor seluruh buku kerja Excel, jadi untuk menempatkan kudanya dalam perlombaan hanya pada kemampuan membaca tampaknya tidak adil; dan xlsReadWritekarena tidak lagi kompatibel dengan versi saya R(sepertinya telah dihapus).

Saya kemudian menjalankan benchmark dengan NN=1000Ldan NN=25000L(mengatur ulang seed sebelum setiap deklarasi di data.frameatas) untuk memungkinkan perbedaan sehubungan dengan ukuran file Excel. gcterutama untuk xlsx, yang saya temukan terkadang dapat membuat penyumbatan memori. Tanpa basa-basi lagi, berikut hasil yang saya temukan:

File Excel 1.000 Baris

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

Begitu readxlpula pemenangnya, dengan openxlsxkompetitif dan gdatapecundang yang jelas. Mengambil setiap ukuran relatif terhadap minimum kolom:

#       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

Kami melihat favorit saya sendiri, xlsx60% lebih lambat dari readxl.

File Excel 25.000 Baris

Karena jumlah waktu yang dibutuhkan, saya hanya melakukan 20 pengulangan pada file yang lebih besar, jika tidak perintahnya identik. Berikut data mentahnya:

# 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

Berikut data relatifnya:

#       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

Begitu readxlpula pemenangnya dalam hal kecepatan. gdatalebih baik lakukan sesuatu yang lain untuk itu, karena sangat lambat dalam membaca file Excel, dan masalah ini hanya diperburuk untuk tabel yang lebih besar.

Dua kekurangannya openxlsxadalah 1) metode lainnya yang ekstensif ( readxldirancang untuk melakukan hanya satu hal, yang mungkin merupakan bagian dari mengapa itu begitu cepat), terutama write.xlsxfungsinya, dan 2) (lebih merupakan kelemahan untuk readxl) col_typesargumen readxlhanya (sebagai dari tulisan ini) menerima beberapa tidak standar R: "text"bukannya "character"dan "date"bukannya "Date".

MichaelChirico
sumber
Akan lebih bagus jika Anda juga menambahkan benchmark untuk XLConnect. Juga beri komentar bahwa readxl tidak dapat ditulis. xlsx dan openxlsx tidak bekerja dengan baik dengan opsi col_types atau colClasses.
skan
@skan Saya awalnya menjalankan beberapa tes dengan XLConnecttetapi sangat lambat; Saya yakin readxlkekurangannya sudah cukup dibahas di paragraf terakhir saya; dan saya tidak memiliki pengalaman serupa dengan Anda dengan xlsxatau openxlsxkarena saya biasa menggunakan keduanya untuk menentukan jenis.
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)

Secara pribadi, saya suka RODBC dan dapat merekomendasikannya.

Brandon Bertelsen
sumber
7
Peringatan: ODBC terkadang sulit dijalankan pada platform selain Windows.
JD Long
1
@JD Long dan bahkan di windows itu PITA. Tidak ada waktu seksi untuk saya dan ODBC pada 64 bit W7 ...
Roman Luštrik
4
Memuat paket yang diperlukan: Kesalahan RODBC di odbcConnectExcel (nama file): odbcConnectExcel hanya dapat digunakan dengan Windows 32-bit
andrekos
6

Solusi lainnya adalah xlsReadWritepaket, yang tidak memerlukan penginstalan tambahan tetapi mengharuskan Anda mengunduh shlib tambahan sebelum Anda menggunakannya pertama kali dengan:

require(xlsReadWrite)
xls.getshlib()

Melupakan hal ini dapat menyebabkan frustrasi. Berada di sana dan semua itu ...

Pada catatan samping: Anda mungkin ingin mempertimbangkan untuk mengonversi ke format berbasis teks (mis. Csv) dan membacanya dari sana. Ini karena sejumlah alasan:

  • apa pun solusi Anda (RODBC, gdata, xlsReadWrite), beberapa hal aneh dapat terjadi saat data Anda dikonversi. Terutama tanggal bisa jadi agak rumit. The HFWutilspaket memiliki beberapa alat untuk berurusan dengan tanggal EXCEL (per komentar @ Ben Bolker ini).

  • jika Anda memiliki lembaran besar, membaca dalam file teks lebih cepat daripada membaca dari EXCEL.

  • untuk file .xls dan .xlsx, solusi yang berbeda mungkin diperlukan. Misalnya, paket xlsReadWrite saat ini tidak mendukung .xlsx AFAIK. gdatamengharuskan Anda menginstal pustaka perl tambahan untuk dukungan .xlsx. xlsxpaket dapat menangani ekstensi dengan nama yang sama.

Joris Meys
sumber
@Ben Thx untuk tipnya, saya akan memasukkannya dalam jawaban saya. Saya tidak mencoba untuk menyelesaikannya, karena halaman wiki tautan jawaban yang diterima sudah agak lengkap. Tapi itu tidak menyebutkan paket HFWutils.
Joris Meys
1
-1; Lihat jawaban saya. TL: DR: Excel tidak menyimpan set data presisi penuh ke csv (atau clipboard). Hanya nilai yang terlihat dipertahankan.
russellpierce
5

Seperti disebutkan di atas dalam banyak jawaban lainnya, ada banyak paket bagus yang terhubung ke file XLS / X dan mendapatkan data dengan cara yang masuk akal. Namun, Anda harus diperingatkan bahwa dalam keadaan apa pun Anda tidak boleh menggunakan clipboard (atau file .csv) untuk mengambil data dari Excel. Untuk melihat alasannya, masuk =1/3ke dalam sel di excel. Sekarang, kurangi jumlah koma desimal yang terlihat menjadi dua. Kemudian salin dan tempel data ke R. Sekarang simpan CSV. Anda akan melihat dalam kedua kasus Excel sangat membantu hanya menyimpan data yang terlihat oleh Anda melalui antarmuka dan Anda telah kehilangan semua ketepatan dalam data sumber Anda yang sebenarnya.

russellpierce
sumber
1
Saya ingin tahu siapa yang menganggap kesetiaan numerik tidak relevan / penting.
russellpierce
1
Peringatan yang bagus. Namun itu tergantung pada paket yang Anda gunakan. beberapa tidak jatuh ke dalam jebakan ini.
RockScience
@RocketScience Ini adalah pilihan desain mendasar dalam ekspor CSV oleh Excel. Apakah Anda memiliki contoh paket yang menggunakan papan klip yang tidak memiliki masalah ini? Paket yang secara langsung mengurai file xls xlsx akan cenderung tidak jatuh ke dalam perangkap ini. Jadi, cakupan spesifik dari peringatan saya.
russellpierce
di Unix, Anda dapat mencoba gnumeric::read.gnumeric.sheet. Pada Windows saya tidak 100% yakin tetapi saya pikir gdata::read.xlsjuga harus bekerja dengan baik (meskipun perlu menginstal perl)
RockScience
@RockScience Hormat kami, gdata :: read.xls tidak beroperasi pada data clipboard (kecuali Anda keluar dari jalan Anda) dan gnumeric bukan Excel. Jadi, tidak ada bukti luar biasa, peringatan saya tetap berlaku. Ada begitu banyak pilihan bagus lainnya untuk menjawab pertanyaan ini - semoga saja orang-orang menggunakannya.
russellpierce
5

Memperluas jawaban yang diberikan oleh @Mikko Anda dapat menggunakan trik yang rapi untuk mempercepat pekerjaan tanpa harus "mengetahui" kelas kolom Anda sebelumnya. Cukup gunakan read.xlsxuntuk mengambil sejumlah catatan untuk menentukan kelas dan kemudian menindaklanjutinya denganread.xlsx2

Contoh

# 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)))
JasonAizkalns
sumber
1
Solusi Anda kembali numericuntuk factorsdi komputer saya. read.xlsxdigunakan characterdalam readColumnsfungsi untuk menentukan faktor. Saya yakin ada cara yang lebih elegan untuk mendapatkan faktor sebagai karakter, tapi di sini adalah versi modifikasi dari fungsi Anda bahwa karya-karya: df.real <- read.xlsx2("filename.xlsx", 1, colClasses=gsub("factor", "character", as.vector(sapply(df.temp, class)))).
Mikko
Ini hanya berfungsi sejauh jenis kolom dapat ditentukan secara memadai oleh baris pertama. Biasanya satu parsing lebih dari baris pertama untuk membuat keputusan itu. Jawabannya dapat ditingkatkan untuk mengatasi komentar aaa90210 dengan menamai paket asal fungsi ini.
russellpierce
1

File Excel dapat dibaca langsung ke R sebagai berikut:

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

Membaca file xls dan xlxs menggunakan paket readxl

library("readxl")
my_data <- read_excel("xxxxx.xls")
my_data <- read_excel("xxxxx.xlsx")
Ashok Kumar Jayaraman
sumber