purrr를 이용하여 Excel 시트들을 읽고 쓰기

준비

작업에 필요한 중요 packages는 purrr, readxl, writexl 이다. tidyvere에는 purrr를 포함하여 dplyr 등과 같이 많이 사용되는 패키지들이 포함되어 있기 때문에 tidyvers를 불러온다.

library(tidyverse)
library(readxl)
library(writexl)

Excel 파일에 다중 시트 동시에 쓰기

예제로 Rdp 기본으로 포함되어 있는 iris 데이터를 이용하고자 한다.

iris %>% head()
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

먼저 iris 데이터를 나누어 여러 개의 데이터셋을 만들고자 한다. Species 변수에 dplyr 패키지의 group_split() 함수를 적용하여 각 꽃의 종류별로 데이터셋을 나눈다.

# 꽃의 종류(Species)별로 데이터를 나눔
iris %>%
  group_split(Species) -> list_of_dfs

list_of_dfs
## <list_of<
##   tbl_df<
##     Sepal.Length: double
##     Sepal.Width : double
##     Petal.Length: double
##     Petal.Width : double
##     Species     : factor<fb977>
##   >
## >[3]>
## [[1]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
##  1          5.1         3.5          1.4         0.2 setosa 
##  2          4.9         3            1.4         0.2 setosa 
##  3          4.7         3.2          1.3         0.2 setosa 
##  4          4.6         3.1          1.5         0.2 setosa 
##  5          5           3.6          1.4         0.2 setosa 
##  6          5.4         3.9          1.7         0.4 setosa 
##  7          4.6         3.4          1.4         0.3 setosa 
##  8          5           3.4          1.5         0.2 setosa 
##  9          4.4         2.9          1.4         0.2 setosa 
## 10          4.9         3.1          1.5         0.1 setosa 
## # ... with 40 more rows
## 
## [[2]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>     
##  1          7           3.2          4.7         1.4 versicolor
##  2          6.4         3.2          4.5         1.5 versicolor
##  3          6.9         3.1          4.9         1.5 versicolor
##  4          5.5         2.3          4           1.3 versicolor
##  5          6.5         2.8          4.6         1.5 versicolor
##  6          5.7         2.8          4.5         1.3 versicolor
##  7          6.3         3.3          4.7         1.6 versicolor
##  8          4.9         2.4          3.3         1   versicolor
##  9          6.6         2.9          4.6         1.3 versicolor
## 10          5.2         2.7          3.9         1.4 versicolor
## # ... with 40 more rows
## 
## [[3]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>    
##  1          6.3         3.3          6           2.5 virginica
##  2          5.8         2.7          5.1         1.9 virginica
##  3          7.1         3            5.9         2.1 virginica
##  4          6.3         2.9          5.6         1.8 virginica
##  5          6.5         3            5.8         2.2 virginica
##  6          7.6         3            6.6         2.1 virginica
##  7          4.9         2.5          4.5         1.7 virginica
##  8          7.3         2.9          6.3         1.8 virginica
##  9          6.7         2.5          5.8         1.8 virginica
## 10          7.2         3.6          6.1         2.5 virginica
## # ... with 40 more rows

purrr 패키지의 map 함수는 특정 함수를 반복적으로 사용하게 해주는 함수이다. lapply 함수 보다 쉽게 사용할 수 있도록 만들어졌다. list_of_dfs에는 꽃의 종류별로 나누어진 3개의 데이터셋이 있다. map 함수를 이용하여 각 데이터셋의 Species 변수를 추출하여 문자로 변환하고(pull 함수, as.character 함수), 고유한 문자를 추출한 후(unique 함수), list_of_dfs의 각 리스트에 이름을 부여하고자 한다.

list_of_dfs %>% 
  map(~pull(.,Species)) %>% 
  map(~as.character(.)) %>% 
  map(~unique(.)) -> names(list_of_dfs)

names(list_of_dfs)
## [1] "setosa"     "versicolor" "virginica"

각 데이터셋의 이름은 데이터를 엑셀로 저장할때 시트의 이름으로 사용하고자 한다.

list_of_dfs %>% 
  write_xlsx("test.xlsx")

엑셀의 다중 시트 동시에 읽기

xl_file <- "test.xlsx"
xl_sheets <- excel_sheets(xl_file)
print(xl_sheets)
## [1] "setosa"     "versicolor" "virginica"
xl_sheets %>% 
  map(function(sheet){
    assign(x = sheet,
           value = read_xlsx(path = xl_file, sheet = sheet),
           envir = .GlobalEnv)
  })
## [[1]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##           <dbl>       <dbl>        <dbl>       <dbl> <chr>  
##  1          5.1         3.5          1.4         0.2 setosa 
##  2          4.9         3            1.4         0.2 setosa 
##  3          4.7         3.2          1.3         0.2 setosa 
##  4          4.6         3.1          1.5         0.2 setosa 
##  5          5           3.6          1.4         0.2 setosa 
##  6          5.4         3.9          1.7         0.4 setosa 
##  7          4.6         3.4          1.4         0.3 setosa 
##  8          5           3.4          1.5         0.2 setosa 
##  9          4.4         2.9          1.4         0.2 setosa 
## 10          4.9         3.1          1.5         0.1 setosa 
## # ... with 40 more rows
## 
## [[2]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
##           <dbl>       <dbl>        <dbl>       <dbl> <chr>     
##  1          7           3.2          4.7         1.4 versicolor
##  2          6.4         3.2          4.5         1.5 versicolor
##  3          6.9         3.1          4.9         1.5 versicolor
##  4          5.5         2.3          4           1.3 versicolor
##  5          6.5         2.8          4.6         1.5 versicolor
##  6          5.7         2.8          4.5         1.3 versicolor
##  7          6.3         3.3          4.7         1.6 versicolor
##  8          4.9         2.4          3.3         1   versicolor
##  9          6.6         2.9          4.6         1.3 versicolor
## 10          5.2         2.7          3.9         1.4 versicolor
## # ... with 40 more rows
## 
## [[3]]
## # A tibble: 50 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
##           <dbl>       <dbl>        <dbl>       <dbl> <chr>    
##  1          6.3         3.3          6           2.5 virginica
##  2          5.8         2.7          5.1         1.9 virginica
##  3          7.1         3            5.9         2.1 virginica
##  4          6.3         2.9          5.6         1.8 virginica
##  5          6.5         3            5.8         2.2 virginica
##  6          7.6         3            6.6         2.1 virginica
##  7          4.9         2.5          4.5         1.7 virginica
##  8          7.3         2.9          6.3         1.8 virginica
##  9          6.7         2.5          5.8         1.8 virginica
## 10          7.2         3.6          6.1         2.5 virginica
## # ... with 40 more rows

source : Martin Chan (2019). Vignette: Write & Read Multiple Excel files with purrr. https://martinctc.github.io/blog/vignette-write-and-read-multiple-excel-files-with-purrr/