fs:tidyverseのファイル操作パッケージ

baseの方法.Rprofileとかでは必要になる。file.path()とか。

baseRの関数との比較

OS非依存でパスを表現

デリミタは常に/、OSに合わせて実際の操作をしてくれる。

関数がベクトル化されている

全ての関数がベクトル化されていて、複数のpathを入力として受けることができる(baseRは全部ではない)

c("docs", "img") %>% 
  fs::dir_info() %>% 
  dplyr::sample_n(10)
## # A tibble: 10 x 18
##    path                            type    size permissions
##    <fs::path>                      <fct> <fs::> <fs::perms>
##  1 docs/tidymodels.html            file   14.8K rw-r--r--  
##  2 docs/mac-Tips.html              file   18.7K rw-r--r--  
##  3 docs/scraping.html              file   14.8K rw-r--r--  
##  4 docs/ggplot2-color.html         file   16.6K rw-r--r--  
##  5 docs/RStan.html                 file     16K rw-r--r--  
##  6 docs/lubridate.html             file   18.1K rw-r--r--  
##  7 docs/R-Tips.html                file     33K rw-r--r--  
##  8 img/RStudio-newVCProject.png    file  277.3K rw-r--r--  
##  9 docs/fs.html                    file   22.4K rw-r--r--  
## 10 img/mac-SysPref-InputSource.png file  263.7K rw-r--r--  
## # … with 14 more variables: modification_time <dttm>, user <chr>,
## #   group <chr>, device_id <dbl>, hard_links <dbl>,
## #   special_device_id <dbl>, inode <dbl>, block_size <dbl>, blocks <dbl>,
## #   flags <int>, generation <dbl>, access_time <dttm>, change_time <dttm>,
## #   birth_time <dttm>

常にpathを伝える予測しやすい返り値を戻す

pathはcharacterベクトル、*_infoだとtibbleで返って来る。

fs::dir_ls() %>% 
  dplyr::glimpse()
##  'fs_path' Named chr [1:95] "EDA.Rmd" "EDA.html" "Excel.Rmd" ...
##  - attr(*, "names")= chr [1:95] "EDA.Rmd" "EDA.html" "Excel.Rmd" "Excel.html" ...
fs::dir_info() %>% 
  dplyr::sample_n(10)
## # A tibble: 10 x 18
##    path               type     size permissions modification_time   user 
##    <fs::path>         <fct> <fs::b> <fs::perms> <dttm>              <chr>
##  1 Rmd-bookdown.html  file   14.91K rw-r--r--   2019-03-04 15:52:41 ytam…
##  2 img                dire…     512 rwxr-xr-x   2019-01-24 09:49:45 ytam…
##  3 dataset.html       file   15.75K rw-r--r--   2019-03-04 15:52:45 ytam…
##  4 Excel.Rmd          file    3.43K rw-r--r--   2019-02-28 22:57:38 ytam…
##  5 PalmWiki.Rproj     file      239 rw-r--r--   2019-03-04 13:50:00 ytam…
##  6 RMarkdown.html     file   22.29K rw-r--r--   2019-03-04 15:52:40 ytam…
##  7 R-Development.html file   14.96K rw-r--r--   2019-03-04 15:52:38 ytam…
##  8 ggplot2.Rmd        file    7.97K rw-r--r--   2019-01-20 11:39:20 ytam…
##  9 scraping.Rmd       file      614 rw-r--r--   2019-01-29 18:37:25 ytam…
## 10 reprex.Rmd         file    1.04K rw-r--r--   2019-01-20 10:11:50 ytam…
## # … with 12 more variables: group <chr>, device_id <dbl>,
## #   hard_links <dbl>, special_device_id <dbl>, inode <dbl>,
## #   block_size <dbl>, blocks <dbl>, flags <int>, generation <dbl>,
## #   access_time <dttm>, change_time <dttm>, birth_time <dttm>
fs::dir_info() %>% 
  names()
##  [1] "path"              "type"              "size"             
##  [4] "permissions"       "modification_time" "user"             
##  [7] "group"             "device_id"         "hard_links"       
## [10] "special_device_id" "inode"             "block_size"       
## [13] "blocks"            "flags"             "generation"       
## [16] "access_time"       "change_time"       "birth_time"
fs::dir_info() %>% 
  dplyr::glimpse()
## Observations: 95
## Variables: 18
## $ path              <fs::path> "EDA.Rmd", "EDA.html", "Excel.Rmd", "Exce…
## $ type              <fct> file, file, file, file, file, file, file, file…
## $ size              <fs::bytes> 540, 14.64K, 3.43K, 18.21K, 6.8K, 22.61K…
## $ permissions       <fs::perms> rw-r--r--, rw-r--r--, rw-r--r--, rw-r--r…
## $ modification_time <dttm> 2019-01-10 11:25:00, 2019-03-04 15:52:37, 201…
## $ user              <chr> "ytamai", "ytamai", "ytamai", "ytamai", "ytama…
## $ group             <chr> "staff", "staff", "staff", "staff", "staff", "…
## $ device_id         <dbl> 16777220, 16777220, 16777220, 16777220, 167772…
## $ hard_links        <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ special_device_id <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ inode             <dbl> 19455000, 24272277, 24002001, 24272395, 209715…
## $ block_size        <dbl> 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096…
## $ blocks            <dbl> 8, 32, 8, 40, 16, 48, 8, 8, 40, 16, 48, 8, 32,…
## $ flags             <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ generation        <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ access_time       <dttm> 2019-03-04 15:52:36, 2019-03-04 15:52:41, 201…
## $ change_time       <dttm> 2019-01-10 11:25:00, 2019-03-04 15:52:38, 201…
## $ birth_time        <dttm> 2019-01-06 20:24:18, 2019-03-04 15:52:37, 201…

はっきりfailしてくれる

fsによる操作が失敗した場合は常にerrorを返す。baseRはwarningとOS依存のエラーコードを返すことが多く、エラーを見逃しやすい。

fs::dir_ls("does_not_exist")
#> Error: [ENOENT] Failed to search directory 'does_not_exist': no such file or directory
dir("does_not_exist")
## character(0)

あ、これはかなり大きい。

どんな時でもUTF-8

baseRはOSのエンコードに依存する。

関数名がわかりやすい

  • path_*はpath関連の操作
  • file_*はファイル操作
  • dir_*はディレクトリの操作
  • link_*はリンクの操作

path系関数

存在確認系

存在、アクセスなど