1.5 데이터 저장하기
readr 패키지가 제공하는 주요 데이터 저장 함수는 write_
로 시작하는데, 다음과 같은 함수들이 있다.
- 쉼표로 구분된 파일로 저장 : write_csv(x, path, na = “NA,” append = FALSE, col_names = !append)
- 임의의 구분자로 구분된 파일로 저장 : write_delim(x, path, delim = " “, na =”NA", append = FALSE, col_names = !append)
- excel의 csv 파일로 저장 : write_excel_csv(x, path, na = “NA,” append = FALSE, col_names = !append)
- 문자열을 파일로 저장 : write_file(x, path, append = FALSE)
- 문자열 벡터를 파일로 저장, 요소 한 개를 한 줄로 저장 : write_lines(x, path, na = “NA,” append = FALSE)
- 개체를 rds 파일로 저장 : write_rds(x, path, compress = c(“none,” “gz,” “bz2,” “xz”), …)
- 탭으로 구분된 파일로 저장 : write_tsv(x, path, na = “NA,” append = FALSE, col_names = !append)
1.5.1 write_csv()
write_csv(challenge, "data1/out/challenge.csv")
challenge
## # A tibble: 2,000 x 2
## x y
## <dbl> <date>
## 1 404 NA
## 2 4172 NA
## 3 3004 NA
## 4 787 NA
## 5 37 NA
## 6 2332 NA
## 7 2489 NA
## 8 1449 NA
## 9 3665 NA
## 10 3863 NA
## # ... with 1,990 more rows
write_csv(challenge, "data1/out/challenge-2.csv")
read_csv("data1/out/challenge-2.csv")
##
## -- Column specification --------------------------------------------------------
## cols(
## x = col_double(),
## y = col_logical()
## )
## Warning: 1000 parsing failures.
## row col expected actual file
## 1001 y 1/0/T/F/TRUE/FALSE 2015-01-16 'data1/out/challenge-2.csv'
## 1002 y 1/0/T/F/TRUE/FALSE 2018-05-18 'data1/out/challenge-2.csv'
## 1003 y 1/0/T/F/TRUE/FALSE 2015-09-05 'data1/out/challenge-2.csv'
## 1004 y 1/0/T/F/TRUE/FALSE 2012-11-28 'data1/out/challenge-2.csv'
## 1005 y 1/0/T/F/TRUE/FALSE 2020-01-13 'data1/out/challenge-2.csv'
## .... ... .................. .......... ...........................
## See problems(...) for more details.
## # A tibble: 2,000 x 2
## x y
## <dbl> <lgl>
## 1 404 NA
## 2 4172 NA
## 3 3004 NA
## 4 787 NA
## 5 37 NA
## 6 2332 NA
## 7 2489 NA
## 8 1449 NA
## 9 3665 NA
## 10 3863 NA
## # ... with 1,990 more rows
1.5.2 write_rds()
write_rds(challenge, "data1/out/challenge.rds")
read_rds("data1/out/challenge.rds")
## # A tibble: 2,000 x 2
## x y
## <dbl> <date>
## 1 404 NA
## 2 4172 NA
## 3 3004 NA
## 4 787 NA
## 5 37 NA
## 6 2332 NA
## 7 2489 NA
## 8 1449 NA
## 9 3665 NA
## 10 3863 NA
## # ... with 1,990 more rows
RDS
,Rdata
,Rda
의 차이점에 대하여 알아보자…- R 데이터 용량 줄이기
1.5.3 write_feather()
library(feather)
write_feather(challenge, "data1/out/challenge.feather")
read_feather("data1/out/challenge.feather")
## # A tibble: 2,000 x 2
## x y
## <dbl> <date>
## 1 404 NA
## 2 4172 NA
## 3 3004 NA
## 4 787 NA
## 5 37 NA
## 6 2332 NA
## 7 2489 NA
## 8 1449 NA
## 9 3665 NA
## 10 3863 NA
## # ... with 1,990 more rows
앞의 예에서 불러온 challenge.csv
데이터 세트를 data1/out
폴더에 저장해 보기로 한다.
<- read_csv(
challenge readr_example("challenge.csv"),
col_types = cols(
x = col_double(),
y = col_date()
)
)tail(challenge)
## # A tibble: 6 x 2
## x y
## <dbl> <date>
## 1 0.805 2019-11-21
## 2 0.164 2018-03-29
## 3 0.472 2014-08-04
## 4 0.718 2015-08-16
## 5 0.270 2020-02-04
## 6 0.608 2019-01-06
readr
에는 디스크에 데이터를 다시 기록하는 데 유용한 함수인 write_csv()
와 write_tsv()
가 있다. 두 함수 모두 다음 동작을 통해 출력 파일이 올바르게 다시 읽힐 수 있게 한다.
- 항상 UTF-8
로 문자열을 인코딩한다.
- 날짜
와 날짜-시간
을 ISO 8601 형식으로 저장하여 어디에서든 쉽게 파싱될 수 있게 한다.
또한, CSV 파일을 엑셀로 내보내려면 write_excel_csv()
를 사용하면 된다. 이는 파일의 시작 부분에 특수 문자(‘byte order mark’)를 작성하여, UTF-8
인코딩을 사용하고 있음을 엑셀에 전달한다.
인수
- 가장 중요한 인수는
x
(저장할 데이터프레임)와path
(그 데이터프레임을 저장할 위치)이다. - 결측값을 지정하는 인수,
na=
와 기존 파일에 첨부할지를 지정하는 인수append=
도 있다.
write_csv(challenge, "data1/out/challenge.csv")
1.5.4 read_csv()
와 read_rds()
의 비교
CSV 로 저장하면 데이터의 유형 정보가 없어진다는 것에 유의하라. 즉, plain text 파일로 저장이 된다.
challenge
## # A tibble: 2,000 x 2
## x y
## <dbl> <date>
## 1 404 NA
## 2 4172 NA
## 3 3004 NA
## 4 787 NA
## 5 37 NA
## 6 2332 NA
## 7 2489 NA
## 8 1449 NA
## 9 3665 NA
## 10 3863 NA
## # ... with 1,990 more rows
write_csv(challenge, "data1/out/challenge-2.csv")
<- read_csv("data1/out/challenge-2.csv") challenge1
##
## -- Column specification --------------------------------------------------------
## cols(
## x = col_double(),
## y = col_logical()
## )
## Warning: 1000 parsing failures.
## row col expected actual file
## 1001 y 1/0/T/F/TRUE/FALSE 2015-01-16 'data1/out/challenge-2.csv'
## 1002 y 1/0/T/F/TRUE/FALSE 2018-05-18 'data1/out/challenge-2.csv'
## 1003 y 1/0/T/F/TRUE/FALSE 2015-09-05 'data1/out/challenge-2.csv'
## 1004 y 1/0/T/F/TRUE/FALSE 2012-11-28 'data1/out/challenge-2.csv'
## 1005 y 1/0/T/F/TRUE/FALSE 2020-01-13 'data1/out/challenge-2.csv'
## .... ... .................. .......... ...........................
## See problems(...) for more details.
str(challenge1)
## tibble [2,000 x 2] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ x: num [1:2000] 404 4172 3004 787 37 ...
## $ y: logi [1:2000] NA NA NA NA NA NA ...
## - attr(*, "problems")= tibble [1,000 x 5] (S3: tbl_df/tbl/data.frame)
## ..$ row : int [1:1000] 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 ...
## ..$ col : chr [1:1000] "y" "y" "y" "y" ...
## ..$ expected: chr [1:1000] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
## ..$ actual : chr [1:1000] "2015-01-16" "2018-05-18" "2015-09-05" "2012-11-28" ...
## ..$ file : chr [1:1000] "'data1/out/challenge-2.csv'" "'data1/out/challenge-2.csv'" "'data1/out/challenge-2.csv'" "'data1/out/challenge-2.csv'" ...
## - attr(*, "spec")=
## .. cols(
## .. x = col_double(),
## .. y = col_logical()
## .. )
x
컬럼은 실수형으로 불러왔으나,y
컬럼은 logical 형으로 불러왔다.
이런 이유로 중간 결과를 캐싱하기에 CSV
파일을 신뢰할 수 없다.
불러올 때마다 열 사양을 다시 만들어야 한다. 즉, parsing을 해 주어야 한다.
여기에는 두 가지 대안이 있다.
write_rds()
와read_rds()
는 베이스 함수인readRDS()
와saveRDS()
의 래퍼 함수들이다. 이들은RDS
라는 R 의 커스텀 바이너리 형식으로 데이터를 저장한다.
write_rds(challenge, "data1/out/challenge.rds")
<- read_rds("data1/out/challenge.rds") challenge2
write_rds()
함수로challenge
데이터 세트를data
폴더에challenge.rds
에 export 했다.read_rds()
함수를 이용하여data1/out/challenge.rds
파일을challenge2
변수로 import 했다.
challenge2
의 데이터 구조를 확인해 보자.
str(challenge2)
## tibble [2,000 x 2] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ x: num [1:2000] 404 4172 3004 787 37 ...
## $ y: Date[1:2000], format: NA NA ...
## - attr(*, "spec")=
## .. cols(
## .. x = col_double(),
## .. y = col_date(format = "")
## .. )
str(challenge2)
으로challenge2
의 데이터 구조를 확인해 보면, 컬럼들의 데이터 타입이 실수형과 날짜형으로 되어 있음을 알 수 있다. 즉, parsing이 필요없다.
feather
패키지는 다른 프로그래밍 언어와 공유할 수 있는 빠른 바이너리 파일 형식을 구현한다.
library(feather)
write_feather(challenge, "data1/out/challenge.feather")
<- read_feather("data1/out/challenge.feather") challenge3
str(challenge3)
## tibble [2,000 x 2] (S3: tbl_df/tbl/data.frame)
## $ x: num [1:2000] 404 4172 3004 787 37 ...
## $ y: Date[1:2000], format: NA NA ...
- x 컬럼과 y 컬럼의 데이터 타입을 잘 읽어 들였다.
feather
는 RDS
보다 대체적으로 빠르며 R 외부에서도 사용할 수 있다.
RDS
는 리스트-열을 지원하지만 feather
는 현재 지원하지 않는다.
따라서, R에서 처리한 데이터 세트는 단순히 csv 파일이 아닌 RDS 파일로 저장하는 것이 좋다. {-}