R이 엑셀 파일을 읽으려면 패키지가 필요합니다
base R은 평문 형식을 기본으로 읽지만 .xlsx는 텍스트가 아닙니다 - XML을 압축한 묶음이고, 그 이전의 .xls는 바이너리 형식이었습니다. 여러분을 기다리는 내장 read.xlsx() 같은 것은 없습니다. 엑셀 파일을 열려면 패키지를 설치해야 하고, 표준 선택지는 readxl 입니다: .xlsx와 .xls를 모두 읽고, 외부 의존성이 없으며(Java도, 엑셀 설치도 필요 없습니다), 한 가지 일을 잘합니다.
install.packages("readxl") # once per machine
library(readxl) # once per session
이 페이지의 예제는 로컬에 readxl이 설치되어 있어야 하므로 실행 가능한 블록이 아니라 정적 코드로 보여 줍니다 - 여러분의 R 세션에서 실행해 보세요. 패키지가 낯설다면 요약은 이렇습니다: install.packages()가 한 번 내려받고, library()가 R을 시작할 때마다 불러옵니다.
read_excel(): 기초
한 번의 호출로 워크북의 첫 시트를 R로 읽어 옵니다:
library(readxl)
sales <- read_excel("sales.xlsx")
head(sales)
str(sales)
다른 임포트와 습관은 같습니다: 모든 열의 타입을 확인하려면 str(), 첫 몇 행을 훑어보려면 head()입니다. 파일을 찾지 못한다면 원인은 거의 항상 작업 디렉터리입니다 - file.exists("sales.xlsx")가 1초 만에 알려 주고, 해결책은 CSV 파일과 같습니다: 전체 경로를 쓰거나 작업 디렉터리를 파일이 있는 폴더로 바꾸세요.
돌아오는 것은 티블(tibble) 입니다 - 데이터 프레임에 대한 tidyverse식 해석이죠. 초보자가 할 모든 작업에서 데이터 프레임과 똑같이 동작합니다(사실 티블은 부가 기능이 붙은 데이터 프레임 입니다): $로 열을 뽑고, nrow()로 행을 세고, dplyr 동사로 흘러갑니다. 눈에 띄는 차이는 겉모습뿐이고 오히려 쾌적합니다 - 전부 쏟아내는 대신 첫 열 개 행만 출력하고 이름 아래에 열 타입을 보여 줍니다. 오래된 함수가 평범한 데이터 프레임을 고집한다면 as.data.frame(sales)로 변환하세요.
시트 고르기, 범위 지정하기, 잡동사니 건너뛰기
실제 워크북이 A1 셀부터 시작하는 깔끔한 표 하나인 경우는 드뭅니다. readxl의 인자들이 흔한 난장판을 처리해 줍니다.
어떤 시트가 있나요? 읽기 전에 물어보세요:
excel_sheets("report.xlsx")
# [1] "Summary" "Q1" "Q2" "Q3" "Raw data"
sheet = 은 이름이나 위치로 하나를 고릅니다:
q3 <- read_excel("report.xlsx", sheet = "Q3")
raw <- read_excel("report.xlsx", sheet = 5)
이름을 쓰는 편이 좋습니다 - 누군가 탭 순서를 바꾸는 날 sheet = 5는 조용히 엉뚱한 시트를 읽습니다.
range = 은 엑셀 자체 표기법으로 정확한 사각형 영역을 읽습니다. 실제 표 주변의 로고 행, 제목 행, 떠도는 메모를 건너뛰는 가장 깔끔한 방법입니다:
budget <- read_excel("budget.xlsx", range = "B4:E20")
budget <- read_excel("budget.xlsx", sheet = "Plan", range = "B4:E20")
skip = 과 col_names = 는 데이터 위에 잡동사니가 몇 줄인지는 알지만 어디서 끝나는지는 모를 때 쓰는 느슨한 대안입니다:
# Data starts after 3 title rows, first real row is the header:
df <- read_excel("export.xlsx", skip = 3)
# No header row at all - supply names yourself:
df <- read_excel("export.xlsx", col_names = c("id", "region", "amount"))
col_names = TRUE(기본값)는 첫 행을 이름으로 사용하고, FALSE는 ...1, ...2를 생성하며 첫 행을 데이터로 취급합니다.
엑셀 쓰기에는 다른 패키지가 필요합니다
readxl은 설계상 읽기 전용입니다. 동료가 결과를 스프레드시트로 원한다면 가장 빠른 길은 writexl 입니다 - 의존성 없는 한 줄이죠:
install.packages("writexl")
writexl::write_xlsx(results, "results.xlsx")
값 이상의 것이 필요하다면 - 굵은 헤더, 틀 고정, 셀 색상, 한 워크북 안의 서식 적용된 여러 시트 - openxlsx 의 영역입니다:
library(openxlsx)
write.xlsx(list(Summary = summary_df, Detail = detail_df), "report.xlsx")
이름 있는 리스트는 원소마다 시트 하나가 됩니다. openxlsx는 엑셀 파일을 읽을 수도 있어서 실무에서 양방향으로 쓰이는 것을 보게 됩니다. 단순히 읽기만 한다면 readxl이 더 간단한 도구입니다.
실용적인 대안: CSV로 내보내기
가끔은 가장 영리하지 않은 해법이 이깁니다. 워크북이 일회성이라면 - 누군가 스프레드시트를 메일로 보냈고 숫자가 지금 필요하다면 - 엑셀에서 열어 "다른 이름으로 저장"으로 시트를 CSV로 내보내고, 이미 아는 도구로 읽으세요:
df <- read.csv("sales.csv")
패키지도, 시트 이름도, 병합된 셀도 없습니다. 전체 워크플로는 CSV 읽기에 있습니다. 대가는 이렇습니다: 다른 시트를 잃고, 서식에 담긴 정보를 잃으며(무언가를 "의미하는" 셀 색상 - 어차피 데이터 설계상 좋지 않은 신호입니다), 원본 파일이 갱신될 때 누군가 잊어버릴 수동 단계가 생깁니다. 반복되는 파이프라인이라면 .xlsx를 직접 읽고, 일회성 임포트라면 CSV로도 솔직히 충분합니다.
전형적인 엑셀 임포트 함정
엑셀 파일에는 CSV에 없는 문제가 따라옵니다. 스프레드시트는 표가 해서는 안 될 일을 사람이 하도록 허용하기 때문입니다.
날짜가 숫자로 들어옵니다. 엑셀은 날짜를 일련의 날짜 수로 저장하므로, 열에 타입이 섞여 있거나 서식이 이상하면 날짜를 기대한 자리에 44688 같은 값이 나올 수 있습니다. readxl은 보통 진짜 날짜 셀을 올바르게 변환하지만, 원시 숫자를 받게 되면 엑셀의 기준일로 변환하세요 - 1970년이 아니라 1899-12-30입니다:
as.Date(44688, origin = "1899-12-30")
# [1] "2022-05-07"
병합된 셀은 빈칸으로 풀립니다. 세 열에 걸쳐 병합된 헤더는 값 하나와 빈 셀 두 개로 돌아오고, 열 개 행에 걸쳐 병합된 범주 라벨은 값 하나와 결측 아홉 개가 됩니다. readxl은 시각적으로만 존재하던 의도를 복원할 수 없습니다 - 임포트 후 그 빈틈을 직접 채워야 한다고 생각하세요.
떠도는 셀 하나가 열 전체를 텍스트로 만듭니다. 열 타입은 데이터에서 추측되므로 "n/a" 하나, 숫자 사이에 적힌 메모, "빈" 셀 안의 공백 하나가 열 전체를 문자형으로 만들 수 있습니다. 읽은 직후의 str()이 이를 잡아냅니다. 추측이 계속 틀린다면 col_types 인자(예: col_types = c("text", "numeric", "date"))로 강제하세요.
핵심 주제는 이렇습니다: 스프레드시트는 사람이 그림을 그리는 캔버스이지 표가 아닙니다. 회의적인 태도로 읽고, str()을 실행하고, 임포트를 믿기 전에 원본과 몇 개 값을 대조해 보세요.
핵심 정리
- base R은
.xlsx를 읽지 못합니다 - readxl 을 설치한 뒤read_excel("file.xlsx")를 쓰세요. excel_sheets()는 워크북의 내용을 나열하고,sheet =(이름 권장)은 하나를 고르며,range = "B4:E20"은 원하는 표만 정확히 잘라 냅니다.- 반환값은 티블입니다 - 출력이 더 보기 좋은 데이터 프레임이죠.
- 쓰기는 다른 패키지를 거칩니다: 단순 출력에는
writexl::write_xlsx(), 서식 있는 워크북에는 openxlsx. - 일회성 작업이라면 엑셀에서 CSV로 내보내
read.csv()를 쓰는 것도 충분히 훌륭한 지름길입니다. - 세 가지 전형적인 문제를 조심하세요: 일련번호로 들어오는 날짜(기준일
1899-12-30), 빈칸이 되는 병합 셀, 그리고 열을 텍스트로 끌어내리는 불량 셀 하나.
다음 주제: 반대 방향 - 데이터 프레임을 CSV와 RDS 파일로 내보내기.
자주 묻는 질문
R에서 엑셀 파일은 어떻게 읽나요?
install.packages("readxl")로 readxl 패키지를 한 번 설치하고 library(readxl)로 불러온 뒤 read_excel("file.xlsx")를 호출합니다. 첫 번째 시트로 만든 티블(현대적인 데이터 프레임)을 반환합니다. 다른 시트를 읽으려면 sheet = 인자에 이름이나 위치를 지정하세요.
패키지 없이 R이 엑셀 파일을 읽을 수 있나요?
아니요. base R에는 .xlsx나 .xls를 읽는 리더가 없습니다 - 이들은 텍스트가 아니라 바이너리/압축 형식입니다. 패키지를 쓰거나(readxl이 표준이고 openxlsx도 됩니다), 엑셀에서 시트를 CSV로 내보내 패키지가 전혀 필요 없는 read.csv()를 쓰면 됩니다.
R에서 엑셀 파일의 특정 시트는 어떻게 읽나요?
read_excel에 sheet =을 전달합니다: 이름으로는 read_excel("report.xlsx", sheet = "Q3"), 위치로는 sheet = 3입니다. 워크북에 무엇이 들어 있는지 모른다면 excel_sheets("report.xlsx")가 모든 시트 이름을 문자 벡터로 반환합니다.
R에서 엑셀 파일은 어떻게 쓰나요?
readxl은 읽기만 합니다. 쓰기용 한 줄 표현은 writexl::write_xlsx(df, "out.xlsx")입니다. 서식이 필요하다면 - 색상, 열 너비, 스타일이 적용된 여러 시트 - 대신 openxlsx 패키지를 쓰세요. 프로그램으로 스타일이 적용된 워크북을 만들 수 있습니다.