IT story

R 스크립트에서 직접 Excel 파일 읽기

hot-time 2020. 8. 29. 12:42
반응형

R 스크립트에서 직접 Excel 파일 읽기


Excel 파일을 R로 직접 읽는 방법은 무엇입니까? 아니면 먼저 데이터를 텍스트 또는 CSV 파일로 내보내고 해당 파일을 R로 가져와야합니까?


예. R wiki의 관련 페이지를 참조하십시오 . 짧은 대답 : 패키지 read.xls에서 gdata대부분의 경우 작동합니다 (시스템에 Perl을 설치해야하지만 일반적으로 MacOS 및 Linux에서는 이미 적용되지만 Windows에서는 추가 단계가 필요합니다 (예 : http://strawberryperl.com/ 참조) . ). R wiki 페이지에는 다양한주의 사항과 대안이 있습니다.

이 작업을 직접 수행하지 않는 유일한 이유는 스프레드 시트에 결함 (이상한 머리글, 여러 워크 시트)이 있는지 확인하기 위해 스프레드 시트를 검사 할 수 있기 때문입니다 (분명히 모든 항목을 반복 할 수 있지만 한 번에 하나씩 만 읽을 수 있음). , 포함 된 플롯 등). 그러나 평범한 숫자와 문자 데이터 (즉, 쉼표 형식의 숫자, 날짜, 0으로 나누기 오류가있는 수식, 결 측값 등이 아닌)가있는 잘 구성된 직사각형 스프레드 시트의 경우 일반적으로 문제가 없습니다. 이 과정에서.


@Chase 권장 사항을 다시 반복하겠습니다 . XLConnect를 사용하십시오 .

XLConnect를 사용하는 이유는 다음과 같습니다.

  1. 크로스 플랫폼. XLConnect는 Java로 작성되므로 R 코드를 변경하지 않고 Win, Linux, Mac에서 실행됩니다 (경로 문자열 제외).
  2. 로드 할 다른 항목이 없습니다. XLConnect를 설치하기 만하면됩니다.
  3. Excel 파일 읽기만 언급했지만 XLConnect는 셀 서식 변경을 포함하여 Excel 파일도 작성합니다. Win뿐만 아니라 Linux 또는 Mac에서도이 작업을 수행합니다.

XLConnect는 다른 솔루션에 비해 다소 새롭기 때문에 블로그 게시물 및 참조 문서에서 자주 언급되지 않습니다. 저에게는 매우 유용했습니다.


그리고 이제 readxl이 있습니다 .

readxl 패키지를 사용하면 Excel에서 R로 데이터를 쉽게 가져올 수 있습니다. 기존 패키지 (예 : gdata, xlsx, xlsReadWrite 등)에 비해 readxl은 외부 종속성이 없으므로 모든 운영 체제에서 쉽게 설치하고 사용할 수 있습니다. 단일 시트에 저장된 테이블 형식 데이터와 함께 작동하도록 설계되었습니다.

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 용) 엑스 코드, 필요 하다 많은 사람들이 다른 이유로 설치 R. 비록 외부 종속성을 .


편집 2015-10 월 : 다른 사람들이 여기에 언급했듯이 openxlsxreadxl패키지는 패키지보다 훨씬 빠르며 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)더 빠르지 만 열 클래스를 수동으로 정의해야합니다. 단축키는 명령을 두 번 실행하는 것입니다 (아래 예 참조). 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)))

Given the proliferation of different ways to read an Excel file in R and the plethora of answers here, I thought I'd try to shed some light on which of the options mentioned here perform the best (in a few simple situations).

I myself have been using xlsx since I started using R, for inertia if nothing else, and I recently noticed there doesn't seem to be any objective information about which package works better.

Any benchmarking exercise is fraught with difficulties as some packages are sure to handle certain situations better than others, and a waterfall of other caveats.

That said, I'm using a (reproducible) data set that I think is in a pretty common format (8 string fields, 3 numeric, 1 integer, 3 dates):

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

I then wrote this to csv and opened in LibreOffice and saved it as an .xlsx file, then benchmarked 4 of the packages mentioned in this thread: xlsx, openxlsx, readxl, and gdata, using the default options (I also tried a version of whether or not I specify column types, but this didn't change the rankings).

I'm excluding RODBC because I'm on Linux; XLConnect because it seems its primary purpose is not reading in single Excel sheets but importing entire Excel workbooks, so to put its horse in the race on only its reading capabilities seems unfair; and xlsReadWrite because it is no longer compatible with my version of R (seems to have been phased out).

I then ran benchmarks with NN=1000L and NN=25000L (resetting the seed before each declaration of the data.frame above) to allow for differences with respect to Excel file size. gc is primarily for xlsx, which I've found at times can create memory clogs. Without further ado, here are the results I found:

1,000-Row Excel File

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

So readxl is the winner, with openxlsx competitive and gdata a clear loser. Taking each measure relative to the column minimum:

#       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

We see my own favorite, xlsx is 60% slower than readxl.

25,000-Row Excel File

Due to the amount of time it takes, I only did 20 repetitions on the larger file, otherwise the commands were identical. Here's the raw data:

# 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

Here's the relative data:

#       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

So readxl is the clear winner when it comes to speed. gdata better have something else going for it, as it's painfully slow in reading Excel files, and this problem is only exacerbated for larger tables.

Two draws of openxlsx are 1) its extensive other methods (readxl is designed to do only one thing, which is probably part of why it's so fast), especially its write.xlsx function, and 2) (more of a drawback for readxl) the col_types argument in readxl only (as of this writing) accepts some nonstandard R: "text" instead of "character" and "date" instead of "Date".


I've had good luck with XLConnect: http://cran.r-project.org/web/packages/XLConnect/index.html


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)

Personally, I like RODBC and can recommend it.


Just gave the package openxlsx a try today. It worked really well (and fast).

http://cran.r-project.org/web/packages/openxlsx/index.html


Another solution is the xlsReadWrite package, which doesn't require additional installs but does require you download the additional shlib before you use it the first time by :

require(xlsReadWrite)
xls.getshlib()

Forgetting this can cause utter frustration. Been there and all that...

On a sidenote : You might want to consider converting to a text-based format (eg csv) and read in from there. This for a number of reasons :

  • whatever your solution (RODBC, gdata, xlsReadWrite) some strange things can happen when your data gets converted. Especially dates can be rather cumbersome. The HFWutils package has some tools to deal with EXCEL dates (per @Ben Bolker's comment).

  • if you have large sheets, reading in text files is faster than reading in from EXCEL.

  • for .xls and .xlsx files, different solutions might be necessary. EG the xlsReadWrite package currently does not support .xlsx AFAIK. gdata requires you to install additional perl libraries for .xlsx support. xlsx package can handle extensions of the same name.


As noted above in many of the other answers, there are many good packages that connect to the XLS/X file and get the data in a reasonable way. However, you should be warned that under no circumstances should you use the clipboard (or a .csv) file to retrieve data from Excel. To see why, enter =1/3 into a cell in excel. Now, reduce the number of decimal points visible to you to two. Then copy and paste the data into R. Now save the CSV. You'll notice in both cases Excel has helpfully only kept the data that was visible to you through the interface and you've lost all of the precision in your actual source data.


Expanding on the answer provided by @Mikko you can use a neat trick to speed things up without having to "know" your column classes ahead of time. Simply use read.xlsx to grab a limited number of records to determine the classes and then followed it up with read.xlsx2

Example

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

An Excel file can be read directly into R as follows:

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

Reading xls and xlxs files using readxl package

library("readxl")
my_data <- read_excel("xxxxx.xls")
my_data <- read_excel("xxxxx.xlsx")

참고URL : https://stackoverflow.com/questions/6099243/read-an-excel-file-directly-from-a-r-script

반응형