├── .RData ├── .Rhistory ├── .Rproj.user ├── 5F53E0D7 │ ├── console06 │ │ ├── B1448F4A │ │ ├── B1448F4A.env │ │ └── INDEX001 │ ├── pcs │ │ ├── files-pane.pper │ │ ├── source-pane.pper │ │ ├── windowlayoutstate.pper │ │ └── workbench-pane.pper │ ├── persistent-state │ ├── rmd-outputs │ ├── saved_source_markers │ └── sources │ │ ├── prop │ │ ├── 15912DE9 │ │ ├── 17B35D8E │ │ ├── 19ED225B │ │ ├── 1EB3F136 │ │ ├── 25612D70 │ │ ├── 2CD3928F │ │ ├── 36FFBF7F │ │ ├── 45AC8244 │ │ ├── 45DE76F3 │ │ ├── 47F14F85 │ │ ├── 4812211F │ │ ├── 4B35AA35 │ │ ├── 54BE33EB │ │ ├── 623ED7F2 │ │ ├── 78C6F526 │ │ ├── 8558E642 │ │ ├── 8ACA37E5 │ │ ├── 977676D5 │ │ ├── A3A451DB │ │ ├── A3B8DD02 │ │ ├── A681361E │ │ ├── ABEA3F22 │ │ ├── BC0CA23D │ │ ├── C5EC0028 │ │ ├── D8DC5DEE │ │ ├── DAAD3860 │ │ ├── DD777DEE │ │ ├── E4CD308C │ │ ├── EA526EF3 │ │ ├── F48429FD │ │ ├── F663482D │ │ ├── F81873B6 │ │ ├── FFEE8EFD │ │ └── INDEX │ │ └── s-7463A4D5 │ │ ├── 48491479 │ │ ├── 13902B70 │ │ ├── 13902B70-contents │ │ ├── 29C9E3DD │ │ ├── 29C9E3DD-contents │ │ ├── 34596095-contents │ │ ├── 48491479-contents │ │ ├── 575E35DA-contents │ │ ├── 58C51A52-contents │ │ ├── 5D8BE6A3-contents │ │ ├── 65FB2C4A-contents │ │ ├── 68CED913-contents │ │ ├── 787A31D6-contents │ │ ├── 8316535A │ │ ├── 8316535A-contents │ │ ├── 8A6FE099-contents │ │ ├── B26C0956 │ │ ├── B26C0956-contents │ │ ├── CC71A08 │ │ ├── CC71A08-contents │ │ ├── D71ACC7B │ │ ├── D71ACC7B-contents │ │ ├── E124C677-contents │ │ ├── F29603B4-contents │ │ ├── F4B20051-contents │ │ └── lock_file └── shared │ └── notebooks │ ├── 1CA9621D-webmining │ └── 1 │ │ ├── 5F53E0D76BB710DA │ │ └── chunks.json │ │ ├── 5F53E0D77463A4D5 │ │ └── chunks.json │ │ ├── 5F53E0D7BC5D4DEC │ │ └── chunks.json │ │ └── s │ │ └── chunks.json │ ├── 57726029-intro │ └── 1 │ │ ├── 5F53E0D77463A4D5 │ │ └── chunks.json │ │ └── s │ │ └── chunks.json │ ├── 95B7313E-basics │ └── 1 │ │ ├── 5F53E0D77463A4D5 │ │ └── chunks.json │ │ └── s │ │ └── chunks.json │ ├── 98AEBD6F-data-wrangling │ └── 1 │ │ └── s │ │ └── chunks.json │ ├── FC61AA20-index │ └── 1 │ │ ├── 5F53E0D74BB9F9B0 │ │ └── chunks.json │ │ ├── 5F53E0D74BED8425 │ │ └── chunks.json │ │ ├── 5F53E0D77463A4D5 │ │ └── chunks.json │ │ ├── 5F53E0D77DF0F42E │ │ └── chunks.json │ │ ├── 5F53E0D7831C07FE │ │ └── chunks.json │ │ ├── 5F53E0D788E0BC1D │ │ └── chunks.json │ │ ├── 5F53E0D78EAAD23E │ │ └── chunks.json │ │ ├── 5F53E0D797F9E39B │ │ └── chunks.json │ │ ├── 5F53E0D7A01679E6 │ │ └── chunks.json │ │ ├── 5F53E0D7B393B584 │ │ └── chunks.json │ │ ├── 5F53E0D7BC5D4DEC │ │ └── chunks.json │ │ ├── 5F53E0D7FD9F7783 │ │ └── chunks.json │ │ └── s │ │ └── chunks.json │ ├── FF18FE3-code-optim │ └── 1 │ │ └── s │ │ └── chunks.json │ ├── patch-chunk-names │ └── paths ├── README.md ├── _book ├── how-to-read-this-book.html ├── index.html ├── intro.html ├── libs │ ├── gitbook-2.6.7 │ │ ├── css │ │ │ ├── fontawesome │ │ │ │ └── fontawesome-webfont.ttf │ │ │ ├── plugin-bookdown.css │ │ │ ├── plugin-fontsettings.css │ │ │ ├── plugin-highlight.css │ │ │ ├── plugin-search.css │ │ │ └── style.css │ │ └── js │ │ │ ├── app.min.js │ │ │ ├── jquery.highlight.js │ │ │ ├── lunr.js │ │ │ ├── plugin-bookdown.js │ │ │ ├── plugin-fontsettings.js │ │ │ ├── plugin-search.js │ │ │ └── plugin-sharing.js │ └── jquery-2.2.3 │ │ └── jquery.min.js ├── optim.html ├── purrr_hex.png ├── purrrcookbook_files │ └── figure-html │ │ ├── unnamed-chunk-11-1.png │ │ └── unnamed-chunk-11-2.png ├── search_index.json ├── stats.html ├── style.css ├── tm.html ├── webmining.html └── wrangling.html ├── _bookdown.yml ├── _bookdown_files └── purrrcookbook_files │ └── figure-html │ ├── unnamed-chunk-10-1.png │ ├── unnamed-chunk-10-2.png │ ├── unnamed-chunk-11-1.png │ ├── unnamed-chunk-11-2.png │ ├── unnamed-chunk-12-1.png │ ├── unnamed-chunk-12-2.png │ ├── unnamed-chunk-6-1.png │ ├── unnamed-chunk-6-2.png │ ├── unnamed-chunk-7-1.png │ ├── unnamed-chunk-7-2.png │ ├── unnamed-chunk-9-1.png │ └── unnamed-chunk-9-2.png ├── _output.yml ├── a.json ├── basics.Rmd ├── book.bib ├── code-optim.Rmd ├── data-wrangling.Rmd ├── docs ├── how-to-read-this-book.html ├── index.html ├── intro.html ├── libs │ ├── gitbook-2.6.7 │ │ ├── css │ │ │ ├── fontawesome │ │ │ │ └── fontawesome-webfont.ttf │ │ │ ├── plugin-bookdown.css │ │ │ ├── plugin-fontsettings.css │ │ │ ├── plugin-highlight.css │ │ │ ├── plugin-search.css │ │ │ └── style.css │ │ └── js │ │ │ ├── app.min.js │ │ │ ├── jquery.highlight.js │ │ │ ├── lunr.js │ │ │ ├── plugin-bookdown.js │ │ │ ├── plugin-fontsettings.js │ │ │ ├── plugin-search.js │ │ │ └── plugin-sharing.js │ └── jquery-2.2.3 │ │ └── jquery.min.js ├── optim.html ├── purrr_hex.png ├── purrrcookbook_files │ └── figure-html │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-11-2.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-12-2.png │ │ ├── unnamed-chunk-7-1.png │ │ └── unnamed-chunk-7-2.png ├── references.html ├── search_index.json ├── stats.html ├── style.css ├── tm.html ├── webmining.html └── wrangling.html ├── index.Rmd ├── intro.Rmd ├── packages.bib ├── preamble.tex ├── purrr_hex.png ├── purrrcookbook.Rproj ├── skeleton ├── statistics.Rmd ├── style.css ├── test.json ├── text-wrangling.Rmd ├── titanic.csv ├── titanic_test.csv ├── titanic_train.csv └── webmining.Rmd /.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.RData -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/console06/B1448F4A.env: -------------------------------------------------------------------------------- 1 | { 2 | "Apple_PubSub_Socket_Render" : "/private/tmp/com.apple.launchd.xVGjGVu0k0/Render", 3 | "CLICOLOR_FORCE" : "1", 4 | "DISPLAY" : "/private/tmp/com.apple.launchd.ZSd4Dea6xb/org.macosforge.xquartz:0", 5 | "EDITOR" : "vi", 6 | "GIT_ASKPASS" : "rpostback-askpass", 7 | "HISTCONTROL" : "ignoreboth", 8 | "HOME" : "/Users/colin", 9 | "LANG" : "fr_FR.UTF-8", 10 | "LC_CTYPE" : "fr_FR.UTF-8", 11 | "LN_S" : "ln -s", 12 | "LOGNAME" : "colin", 13 | "MAKE" : "make", 14 | "PAGER" : "/usr/bin/less", 15 | "PATH" : "/Library/Frameworks/Python.framework/Versions/3.6/bin:/Users/colin/anaconda/bin:/Users/colin/anaconda3/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/share/dotnet:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Library/TeX/texbin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Users/colin/anaconda/bin:/Users/colin/anaconda3/bin:bin/msys-ssh-1000-18", 16 | "PROMPT_COMMAND" : "echo -ne \"\\033]0;${PWD/#${HOME}/~}\\007\"", 17 | "PWD" : "/Users/colin/Seafile/documents_colin/R/purrrcookbook", 18 | "RMARKDOWN_MATHJAX_PATH" : "/Applications/RStudio.app/Contents/Resources/resources/mathjax-26", 19 | "RSTUDIO" : "1", 20 | "RSTUDIO_CONSOLE_COLOR" : "256", 21 | "RSTUDIO_CONSOLE_WIDTH" : "88", 22 | "RSTUDIO_PANDOC" : "/Applications/RStudio.app/Contents/MacOS/pandoc", 23 | "RSTUDIO_PROJ_NAME" : "purrrcookbook", 24 | "RSTUDIO_SESSION_ID" : "7463A4D5", 25 | "RSTUDIO_SESSION_PORT" : "12641", 26 | "RSTUDIO_TERM" : "B1448F4A", 27 | "RSTUDIO_USER_IDENTITY" : "colin", 28 | "RSTUDIO_WINUTILS" : "bin/winutils", 29 | "RS_RPOSTBACK_PATH" : "/Applications/RStudio.app/Contents/MacOS/rpostback", 30 | "RS_SHARED_SECRET" : "d02bffdb-8e7e-4adf-8b20-789f7fc70776", 31 | "R_BROWSER" : "/usr/bin/open", 32 | "R_BZIPCMD" : "/usr/bin/bzip2", 33 | "R_DOC_DIR" : "/Library/Frameworks/R.framework/Resources/doc", 34 | "R_GZIPCMD" : "/usr/bin/gzip", 35 | "R_HOME" : "/Library/Frameworks/R.framework/Resources", 36 | "R_INCLUDE_DIR" : "/Library/Frameworks/R.framework/Resources/include", 37 | "R_LIBS_SITE" : "", 38 | "R_LIBS_USER" : "~/Library/R/3.4/library", 39 | "R_LOCAL_CACHE" : ".R_Store", 40 | "R_PAPERSIZE" : "a4", 41 | "R_PDFVIEWER" : "/usr/bin/open", 42 | "R_PLATFORM" : "x86_64-apple-darwin15.6.0", 43 | "R_PRINTCMD" : "lpr", 44 | "R_QPDF" : "/Library/Frameworks/R.framework/Resources/bin/qpdf", 45 | "R_RD4PDF" : "times,inconsolata,hyper", 46 | "R_SESSION_TMPDIR" : "/var/folders/lz/thnnmbpd1rz0h1tmyzgg0mh00000gn/T//Rtmp3P5fkg", 47 | "R_SHARE_DIR" : "/Library/Frameworks/R.framework/Resources/share", 48 | "R_SYSTEM_ABI" : "osx,gcc,gxx,gfortran,?", 49 | "R_TEXI2DVICMD" : "/usr/local/bin/texi2dvi", 50 | "R_UNZIPCMD" : "/usr/bin/unzip", 51 | "R_ZIPCMD" : "/usr/bin/zip", 52 | "SED" : "/usr/bin/sed", 53 | "SHELL" : "/bin/bash", 54 | "SHLVL" : "3", 55 | "SSH_ASKPASS" : "rpostback-askpass", 56 | "SSH_AUTH_SOCK" : "/private/tmp/com.apple.launchd.6DfAHTBWfI/Listeners", 57 | "TAR" : "/usr/bin/tar", 58 | "TERM" : "xterm-256color", 59 | "TMPDIR" : "/var/folders/lz/thnnmbpd1rz0h1tmyzgg0mh00000gn/T/", 60 | "USER" : "colin", 61 | "XPC_FLAGS" : "0x0", 62 | "XPC_SERVICE_NAME" : "0", 63 | "__CF_USER_TEXT_ENCODING" : "0x1F5:0x0:0x1", 64 | "__KMP_REGISTERED_LIB_2442" : "0x1018ab7e8-cafeb092-libomp.dylib" 65 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/console06/INDEX001: -------------------------------------------------------------------------------- 1 | [{"allow_restart":true,"alt_buffer":false,"autoclose":1,"buffered_output":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","caption":"Terminal 1","channel_id":"5751","channel_mode":1,"child_procs":false,"cols":77,"cwd":"~/Seafile/documents_colin/R/purrrcookbook","exit_code":null,"handle":"B1448F4A","interaction_mode":2,"max_output_lines":1000,"restarted":true,"rows":12,"shell_type":7,"show_on_output":false,"terminal_sequence":1,"title":"~/Seafile/documents_colin/R/purrrcookbook","track_env":true,"zombie":false}] -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/pcs/files-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "path" : "~/Seafile/documents_colin/R/purrrcookbook", 3 | "sortOrder" : [ 4 | { 5 | "ascending" : true, 6 | "columnIndex" : 2 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/pcs/source-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "activeTab" : 0 3 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/pcs/windowlayoutstate.pper: -------------------------------------------------------------------------------- 1 | { 2 | "left" : { 3 | "panelheight" : 963, 4 | "splitterpos" : 418, 5 | "topwindowstate" : "NORMAL", 6 | "windowheight" : 1001 7 | }, 8 | "right" : { 9 | "panelheight" : 963, 10 | "splitterpos" : 807, 11 | "topwindowstate" : "NORMAL", 12 | "windowheight" : 1001 13 | } 14 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/pcs/workbench-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "TabSet1" : 0, 3 | "TabSet2" : 4, 4 | "TabZoom" : { 5 | } 6 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/persistent-state: -------------------------------------------------------------------------------- 1 | build-last-errors="[]" 2 | build-last-errors-base-dir="" 3 | build-last-outputs="[]" 4 | compile_pdf_state="{\"errors\":[],\"output\":\"\",\"running\":false,\"tab_visible\":false,\"target_file\":\"\"}" 5 | files.monitored-path="" 6 | find-in-files-state="{\"handle\":\"\",\"input\":\"\",\"path\":\"\",\"regex\":true,\"results\":{\"file\":[],\"line\":[],\"lineValue\":[],\"matchOff\":[],\"matchOn\":[]},\"running\":false}" 7 | imageDirtyState="1" 8 | saveActionState="-1" 9 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/rmd-outputs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/saved_source_markers: -------------------------------------------------------------------------------- 1 | {"active_set":"","sets":[]} -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/15912DE9: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "87,13", 3 | "scrollLine" : "81" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/17B35D8E: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "0,19", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/19ED225B: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/1EB3F136: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "18,63", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/25612D70: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "14,18", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/2CD3928F: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/36FFBF7F: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/45AC8244: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "19,0", 3 | "scrollLine" : "0", 4 | "tempName" : "Untitled1" 5 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/45DE76F3: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "72,0", 3 | "scrollLine" : "48" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/47F14F85: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "189,24", 3 | "scrollLine" : "180" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/4812211F: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "2,107", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/4B35AA35: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "55,136", 3 | "scrollLine" : "41" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/54BE33EB: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/623ED7F2: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "12,39", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/78C6F526: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "0,0", 3 | "scrollLine" : "0", 4 | "tempName" : "Untitled1" 5 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/8558E642: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/8ACA37E5: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "112,21", 3 | "scrollLine" : "102" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/977676D5: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "13,29", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/A3A451DB: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "0,0", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/A3B8DD02: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "39,90", 3 | "scrollLine" : "28" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/A681361E: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "2,45", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/ABEA3F22: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "1,0", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/BC0CA23D: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/C5EC0028: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/D8DC5DEE: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/DAAD3860: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/DD777DEE: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "0,19", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/E4CD308C: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/EA526EF3: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "2,7", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/F48429FD: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "3,14", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/F663482D: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "13,29", 3 | "scrollLine" : "0" 4 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/F81873B6: -------------------------------------------------------------------------------- 1 | { 2 | "cursorPosition" : "124,130", 3 | "docOutlineVisible" : "1", 4 | "scrollLine" : "106" 5 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/FFEE8EFD: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/prop/INDEX: -------------------------------------------------------------------------------- 1 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrr%2FR%2Fas_mapper.R="BC0CA23D" 2 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrr%2FR%2Fcoercion.R="FFEE8EFD" 3 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F01-basics.Rmd="F48429FD" 4 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F01-intro.Rmd="4812211F" 5 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F02-literature.Rmd="2CD3928F" 6 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F02-statistics.Rmd="47F14F85" 7 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F02-webmining.Rmd="EA526EF3" 8 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F03-method.Rmd="8558E642" 9 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F03-statistics.Rmd="8ACA37E5" 10 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F03-webmining.Rmd="15912DE9" 11 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F04-application.Rmd="54BE33EB" 12 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F04-text-wrangling.Rmd="45DE76F3" 13 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F05-code-optim.Rmd="DD777DEE" 14 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F05-summary.Rmd="DAAD3860" 15 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F06-data-wrangling.Rmd="977676D5" 16 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F06-references.Rmd="C5EC0028" 17 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2FREADME.md="A681361E" 18 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F_bookdown.yml="25612D70" 19 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2F_output.yml="1EB3F136" 20 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fbasics.Rmd="F81873B6" 21 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fbook.bib="36FFBF7F" 22 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fcode-optim.Rmd="17B35D8E" 23 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fdata-wrangling.Rmd="F663482D" 24 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Findex.Rmd="A3B8DD02" 25 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fintro.Rmd="4B35AA35" 26 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fpackages.bib="A3A451DB" 27 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fpurrrcookbook.Rmd="E4CD308C" 28 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Freferences.Rmd="ABEA3F22" 29 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fskeleton="45AC8244" 30 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fstyle.css="D8DC5DEE" 31 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Ftest.json="78C6F526" 32 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fpurrrcookbook%2Fwebmining.Rmd="623ED7F2" 33 | ~%2FSeafile%2Fdocuments_colin%2FR%2Fwhereshouldwe.R="19ED225B" 34 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/13902B70: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516363200897.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "13902B70", 10 | "lastKnownWriteTime" : 1516395549, 11 | "last_content_update" : 1516395549143, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/index.Rmd", 13 | "project_path" : "index.Rmd", 14 | "properties" : { 15 | "cursorPosition" : "39,90", 16 | "scrollLine" : "28" 17 | }, 18 | "relative_order" : 4, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "r_markdown" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/13902B70-contents: -------------------------------------------------------------------------------- 1 | --- 2 | title: "purrr cookbook" 3 | author: "Colin Fay" 4 | date: "Last update on: `r Sys.Date()`" 5 | knit: "bookdown::render_book" 6 | site: bookdown::bookdown_site 7 | output: bookdown::gitbook 8 | documentclass: book 9 | bibliography: [book.bib, packages.bib] 10 | biblio-style: apalike 11 | link-citations: true 12 | links-as-notes: true 13 | colorlinks: true 14 | description: "A {purrr} cookbookdown." 15 | --- 16 | 17 | ```{r include=FALSE} 18 | # automatically create a bib database for R packages 19 | knitr::write_bib(c( 20 | .packages(), 'bookdown', 'knitr', 'rmarkdown', 'purrr' 21 | ), 'packages.bib') 22 | ``` 23 | 24 | # Welcome {-} 25 | 26 |
27 | 28 | ```{r echo=FALSE, fig.align='center'} 29 | knitr::include_graphics("purrr_hex.png") 30 | ``` 31 | 32 |
33 | 34 | This "cookbookdown" covers a series of common receipes you can do with {purrr}. 35 | 36 | It's based on several blogposts written on [colinfay.me](http://colinfay.me/tags/purrr/), some {purrr} code shared [on Twitter](https://twitter.com/i/moments/950031718521671680), and on some use-cases found or fought in the wild wild data world. 37 | 38 | As with any cookbook, this bookdwon is not intended at explaining in details what {purrr} does or how the functions used works. There is a short discussion after each receipes to quickly explain what the code does, but we won't go into specific details about each piece of code. For example, you won't find an explanation on the Shapiro Test in the chapter talking about this test. I also try to include (as much as possible) references to other articles / blogposts / books that can help you go deeper. 39 | 40 | And if ever you need more explanation, reach me on [Twitter](https://twitter.com/_ColinFay)! -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/29C9E3DD: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516394739017.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "29C9E3DD", 10 | "lastKnownWriteTime" : 1516396425, 11 | "last_content_update" : 1516396425866, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/basics.Rmd", 13 | "project_path" : "basics.Rmd", 14 | "properties" : { 15 | "cursorPosition" : "124,130", 16 | "docOutlineVisible" : "1", 17 | "scrollLine" : "106" 18 | }, 19 | "relative_order" : 7, 20 | "source_on_save" : false, 21 | "source_window" : "", 22 | "type" : "r_markdown" 23 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/29C9E3DD-contents: -------------------------------------------------------------------------------- 1 | # purrr basics {#intro} 2 | 3 | ```{r echo = FALSE} 4 | library(purrr) 5 | ``` 6 | 7 | ## map function 8 | 9 | ### I want to... 10 | 11 | Start using {purrr}. 12 | 13 | ### Here's how to: 14 | 15 | The base skeleton of {purrr} iteration functions are: 16 | 17 | ```{r eval = FALSE} 18 | library(purrr) 19 | map(.x, .f, ...) 20 | ``` 21 | 22 | ### Ok, but why? 23 | 24 | In this skeleton: 25 | 26 | + `.x` is a list, a data.frame or a vector. 27 | + `.f` is the function, formula or atomic vector that will be applied on each element of `.f`. 28 | 29 | Here, what `map` does is applying the function to each element of a list. The returned object is always a list. 30 | 31 | ### See also 32 | 33 | + [A introduction to purrr](https://github.com/cwickham/purrr-tutorial) 34 | 35 | --- 36 | 37 | ## map_* functions 38 | 39 | ### I want to... 40 | 41 | Control the output of my iterations. 42 | 43 | ### Here's how to: 44 | 45 | ```{r} 46 | # Returns a dbl 47 | map_dbl(1:10, sqrt) 48 | ``` 49 | 50 | ### Ok, but why? 51 | 52 | You can control the output of your map with these functions: `map_lgl` `map_chr` `map_int` `map_dbl` `map_dfr` `map_dfc`. 53 | 54 | ### See also 55 | 56 | + [R for Data Science - 21.5 The map functions](http://r4ds.had.co.nz/iteration.html#the-map-functions) 57 | 58 | --- 59 | 60 | ## Mappers 61 | 62 | ### I want to... 63 | 64 | Create a function on the fly. 65 | 66 | ### Here's how to: 67 | 68 | ```{r} 69 | map_dbl(1:10, ~ .x + 2) 70 | ``` 71 | 72 | ### Ok, but why? 73 | 74 | One sided formulaes, also called mappers, can be created as the `.f` argument of map. It is build with `~`, then `.x` refers to the element of the list in `.x`. 75 | 76 | When mapping on two elements, you can use `.x` and `.y`. With more than two elements, refer to them with `..1`, `..2`, `..3`, etc. 77 | 78 | ### See also 79 | 80 | + [R for Data Science - 21.5.1 Shortcuts](http://r4ds.had.co.nz/iteration.html#shortcuts) 81 | 82 | --- 83 | 84 | ## map on 2 elements 85 | 86 | ### I want to... 87 | 88 | map over two lists. 89 | 90 | ### Here's how to: 91 | 92 | ```{r} 93 | map2_chr(letters, LETTERS, paste) 94 | ``` 95 | 96 | ### Ok, but why? 97 | 98 | `map2` and friends (`map2` `map2_lgl` `map2_int` `map2_dbl` `map2_chr` `map2_dfr` `map2_dfc`) allows to map over two elements. 99 | 100 | ### See also 101 | 102 | + [R for Data Science - 21.7 Mapping over multiple arguments](http://r4ds.had.co.nz/iteration.html#dealing-with-failure) 103 | 104 | --- 105 | 106 | ## map on more elements 107 | 108 | ### I want to... 109 | 110 | map over more than two lists. 111 | 112 | ### Here's how to: 113 | 114 | ```{r} 115 | l <- list(a = 1:3, b = 2:4, c = 3:5) 116 | pmap_dbl(l, ~ ..1 + ..2 + ..3) 117 | ``` 118 | 119 | ### Ok, but why? 120 | 121 | `pmap` and friends (`pmap_lgl` `pmap_int` `pmap_dbl` `pmap_chr` `pmap_dfr` `pmap_dfc`) allows to map over more than two elements. 122 | 123 | ### See also 124 | 125 | + [R for Data Science - 21.7 Mapping over multiple arguments](http://r4ds.had.co.nz/iteration.html#mapping-over-multiple-arguments) 126 | 127 | --- 128 | 129 | ## Iteration for side effect 130 | 131 | ### I want to... 132 | 133 | Iterate only for side effect. 134 | 135 | ### Here's how to: 136 | 137 | ```{r} 138 | walk(1:2, plot) 139 | ``` 140 | 141 | ### Ok, but why? 142 | 143 | `walk` is the silent conterpart of map, but invisible: you call it just for side effects. `map_*`, `map2_*`, `pwalk` and friends also exists. 144 | 145 | ### See also 146 | 147 | + [R for Data Science - 21.8 Walk](http://r4ds.had.co.nz/iteration.html#walk) 148 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/34596095-contents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/34596095-contents -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/48491479: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516398210736.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "48491479", 10 | "lastKnownWriteTime" : 1516398234, 11 | "last_content_update" : 1516398234763, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/README.md", 13 | "project_path" : "README.md", 14 | "properties" : { 15 | "cursorPosition" : "2,45", 16 | "scrollLine" : "0" 17 | }, 18 | "relative_order" : 6, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "markdown" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/48491479-contents: -------------------------------------------------------------------------------- 1 | ## A purrr cookbook 2 | 3 | > Disclaimer: this is still a work in progree 4 | 5 | A series of {purrr} common receipes as a cookbookdown. 6 | 7 | Losely based on a series of [blogposts](http://colinfay.me/tags/purrr/), and this [Twitter moment](https://twitter.com/i/moments/950031718521671680). -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/575E35DA-contents: -------------------------------------------------------------------------------- 1 | json_object <- '[ 2 | { 3 | "id": "066062", 4 | "name": "Observatory Hill", 5 | "label": "Sydney City", 6 | "tz": "Australia/Sydney", 7 | "record_start": "1910", 8 | "record_end": "2017" 9 | }, 10 | { 11 | "id": "067105", 12 | "name": "Richmond RAAF", 13 | "label": "Sydney West", 14 | "tz": "Australia/Sydney", 15 | "record_start": "1939", 16 | "record_end": "2017" 17 | } 18 | ]' 19 | a <- tempdir() 20 | write(json_object, file.path(a, "a.json")) 21 | stations <- jsonlite::fromJSON(file.path(a, "a.json")) 22 | 23 | 24 | stations = RJSONIO::fromJSON("https://goo.gl/U7C3MP") 25 | 26 | map(stations, "name") 27 | stations %>% map(~ pluck(., "name")) 28 | 29 | 30 | library(tidyverse) # purrr is in here! 31 | library(RJSONIO) 32 | 33 | stations = fromJSON("https://goo.gl/U7C3MP") 34 | str(stations) 35 | 36 | stations %>% :pluck(3, "name") 37 | 38 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/58C51A52-contents: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## 4 | 5 | ### I want to... 6 | 7 | 8 | ### Here's how to: 9 | 10 | ```{r} 11 | 12 | ``` 13 | 14 | ### Ok, but why? 15 | 16 | 17 | 18 | ### See also 19 | 20 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/65FB2C4A-contents: -------------------------------------------------------------------------------- 1 | # How to read this book {-} 2 | 3 | This book is divided in `r length(list.files(pattern = "Rmd")) - 4` chapters. 4 | 5 | Each chapter contains a random number of receipes, more or less from the easiest to more complex examples. 6 | 7 | - "Statistics" contains a list of useful common stat tricks with {purrr} 8 | - "Webmining" gives you elements to mine info from the web (HTML / JSON) 9 | - "Text Wrangling" covers some text mining methods 10 | - "Code optimisation" is a chapter about using {purrr} to write better code 11 | - "Data Wrangling" is a list of receipes I couldn't fit anywhere else ¯\\_(ツ)_/¯ 12 | 13 | Based on other programming cookbook template, each receipe is divided as such: 14 | 15 | - "I want to...": what you want to do 16 | - "Here's how to": how to do this 17 | - "Ok, but why?": more explanations about the solution 18 | - "See also": further references if you want to go deeper 19 | 20 | ## Who is this cookbook for? {-} 21 | 22 | Anybody interested in learning more about {purrr}, either by reading this from cover to cover (well... figuratively speaking), of by picking what you find interesting. 23 | 24 | ## Before reading {-} 25 | 26 | We expect the reader to be a little bit familiar with R, and with the core packages from the tidyverse. 27 | 28 | Copy and paste the below code to be sure you have all the packages you need. 29 | 30 | ```{r eval = FALSE} 31 | install.packages("tidyverse") 32 | install.packages("broom") 33 | install.packages("rvest") 34 | install.packages("attempt") 35 | install.packages("tidystringdist") 36 | install.packages("tidytext") 37 | ``` 38 | 39 | Let's launch the tidyverse to be sure we have everything we need: 40 | 41 | ```{r} 42 | library(tidyverse) 43 | ``` 44 | 45 | 46 | ## You want another receipe {-} 47 | 48 | For another receipe, please ask on this issue. 49 | 50 | ## You want to share a receipe {-} 51 | 52 | I'll be glad to add other {purrr} receipes, so if ever you want to share one (or more), feel free to make a PR on the GitHub repo. 53 | 54 | ## What to do if you find a typo {-} 55 | 56 | Nobody's perfect and this book might contains typos. So please, yes please, open a PR (or feel free to reach me on [Twitter](https://twitter.com/_ColinFay)) 57 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/68CED913-contents: -------------------------------------------------------------------------------- 1 | bookdown::pdf_book: 2 | includes: 3 | in_header: preamble.tex 4 | latex_engine: xelatex 5 | citation_package: natbib 6 | keep_tex: yes 7 | bookdown::epub_book: default 8 | bookdown::gitbook: 9 | css: style.css 10 | df_print: kable 11 | config: 12 | toc: 13 | collapse: section 14 | before: | 15 |
  • A purrr cookbook
  • 16 | after: | 17 |
  • Written by Colin Fay
  • 18 |
  • Published with bookdown
  • 19 |
  • Hosted on Github
  • 20 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/787A31D6-contents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/787A31D6-contents -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/8316535A: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516363401681.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "8316535A", 10 | "lastKnownWriteTime" : 1516397613, 11 | "last_content_update" : 1516397613795, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/webmining.Rmd", 13 | "project_path" : "webmining.Rmd", 14 | "properties" : { 15 | "cursorPosition" : "12,39", 16 | "scrollLine" : "0" 17 | }, 18 | "relative_order" : 4, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "r_markdown" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/8316535A-contents: -------------------------------------------------------------------------------- 1 | # Webmining {#webmining} 2 | 3 | ## Status code 4 | 5 | ### I want to... 6 | 7 | Create a status code checker. 8 | 9 | ### Here's how to 10 | 11 | ```{r} 12 | library(httr) 13 | get_status <- compose(status_code, GET) 14 | get_status("colinfay.me") 15 | ``` 16 | 17 | ### Ok, but why? 18 | 19 | `compose(y, x)` composes a function that will do `y(x())`. So here, `get_status("url")` will do `status_code(GET("url"))`. 20 | 21 | ### See also 22 | 23 | --- 24 | 25 | ## Check status code 26 | 27 | ### I want to... 28 | 29 | Check for http status code for a list of pages. 30 | 31 | ### Here's how to 32 | 33 | ```{r} 34 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 35 | get_status <- compose(status_code, GET) 36 | map(urls, get_status) %>% every(~ .x == 200) 37 | ``` 38 | 39 | ### Ok, but why? 40 | 41 | 200 is a status code that indicates that the connexion went smoothly. The `every` function here checks if all the status code we just `GET` are equal to 200. 42 | 43 | ### See also 44 | 45 | --- 46 | ## Clean a list of urls 47 | 48 | ### I want to... 49 | 50 | Keep only the 200 codes from my list of `urls`. 51 | 52 | ### Here's how to 53 | 54 | ```{r} 55 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 56 | get_status <- compose(status_code, GET) 57 | map(urls, get_status) %>% set_names(nm = urls) %>% keep(~ .x == 200) 58 | ``` 59 | 60 | ### Ok, but why? 61 | 62 | `set_names` sets the name for all the elements from the list. You can either leave the function with just the list as first arg, or pass it another list of the same length as `x`. 63 | 64 | `keep` only keeps the elements that validate the condition. 65 | 66 | ### See also 67 | 68 | --- 69 | ## Scrape a list of urls which may fail 70 | 71 | ### I want to... 72 | 73 | Launch a `read_html` function on a list of webpages, and some may throw an error. 74 | 75 | The difference with the function we saw previously ? 76 | 77 | ```{r error = TRUE} 78 | # http status code error 79 | GET("notexistingurl") 80 | # Error because host doesn't exist 81 | GET("notexistingurl.org") 82 | ``` 83 | 84 | 85 | ### Here's how to 86 | 87 | ```{r} 88 | library(rvest) 89 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 90 | possible_read <- possibly(read_html, otherwise = NULL) 91 | map(urls, possible_read) %>% set_names(urls) %>% compact() 92 | ``` 93 | 94 | ### Ok, but why 95 | 96 | `possibly` turns a function into another function that returns what is defined in otherwise in case of failure. Here, we chose to return NULL. 97 | 98 | `compact()` removes all the elements from a list which are NULL. 99 | 100 | ### See also 101 | 102 | + [R for Data Science - 21.6 Dealing with failure](http://r4ds.had.co.nz/iteration.html#dealing-with-failure) 103 | 104 | --- 105 | 106 | ## Getting h2 107 | 108 | ### I want to... 109 | 110 | Get the h2s from a list of urls. 111 | 112 | ### Here's how to 113 | 114 | ```{r} 115 | get_h2 <- compose(html_text, 116 | as_mapper(~ html_nodes(.x, "h2")), 117 | read_html) 118 | urls <- c("http://colinfay.me", "http://thinkr.fr") 119 | map(urls, get_h2) %>% set_names(urls) 120 | ``` 121 | 122 | ### Ok, but why? 123 | 124 | We are composing an h2 extractor by combining `read_html`, `html_nodes` and `html_text`. We then map this extractor to a list of urls, before setting the names of the results with the `set_names` function. 125 | 126 | ### See also 127 | 128 | --- 129 | ## Scrape JSON 130 | 131 | Given the following JSON files: 132 | 133 | ``` 134 | { 135 | "obs1": { 136 | "id": "AA", 137 | "Age": "29", 138 | "Res": { 139 | "test1": "17", 140 | "test2": "12" 141 | } 142 | }, 143 | "obs2": { 144 | "id": "BB", 145 | "Age": "35", 146 | "Res": { 147 | "test1": "12", 148 | "test2": "5" 149 | } 150 | } 151 | } 152 | ``` 153 | ```{r} 154 | json_file <- jsonlite::read_json("test.json") 155 | ``` 156 | 157 | ### I want to... 158 | 159 | Extract all the elements in "value". 160 | 161 | ### Here's how to: 162 | 163 | ```{r} 164 | map(json_file, "id") 165 | ``` 166 | 167 | ### Ok, but why? 168 | 169 | If you put a character vector as `.f`, `map` looks for all the elements with the name matching this vector. This call works for the first level of the list 170 | 171 | ### See also 172 | 173 | --- 174 | 175 | ## JSON with many levels 176 | 177 | ### I want to... 178 | 179 | Extract all the test1 results. 180 | 181 | ### Here's how to: 182 | 183 | ```{r} 184 | map(json_file, ~ purrr::pluck(.x, "Res", "test1")) 185 | ``` 186 | 187 | ### Ok, but why 188 | 189 | What we called before is a shortcut for `map(file, ~ pluck(.x, "id")`. That shortcut works on the first level of the list. If you need to go deeper, you need to explicitely specify the `pluck` call. 190 | 191 | Be careful, there is also a `pluck` in {rvest} that doesn't behave exactly as the `pluck` from {purrr}. 192 | 193 | ```{r error=TRUE} 194 | map(json_file, ~ rvest::pluck(.x, "Res", "test1")) 195 | ``` 196 | 197 | 198 | ### See also 199 | 200 | --- 201 | 202 | ## Several API call 203 | 204 | ### I want to... 205 | 206 | Make a series of API calls 207 | 208 | ### Here's how to: 209 | 210 | ```{r warning=FALSE} 211 | library(attempt) 212 | library(curl) 213 | caller <- function(x){ 214 | # verify internet connexion 215 | stop_if_not(has_internet(), msg = "You should have internet to do that") 216 | res <- GET(url = "https://geo.api.gouv.fr/communes", query = list(nom = x)) 217 | res$content %>% rawToChar() %>% jsonlite::fromJSON(simplifyDataFrame = TRUE) 218 | } 219 | city <- c("Rennes","Vannes","Brest") 220 | map_df(city, caller) 221 | ``` 222 | 223 | ### Ok, but why? 224 | 225 | Here, we are calling an API which returns a JSON object that can be easily turned into a df with {jsonlite}. So we choose to use `map_df` to return a simple data.frame of the three results. 226 | 227 | ### See also 228 | 229 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/8A6FE099-contents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/8A6FE099-contents -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/B26C0956: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516348055128.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "B26C0956", 10 | "lastKnownWriteTime" : 1516347151, 11 | "last_content_update" : 1516347151, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/code-optim.Rmd", 13 | "project_path" : "code-optim.Rmd", 14 | "properties" : { 15 | "cursorPosition" : "0,19", 16 | "scrollLine" : "0" 17 | }, 18 | "relative_order" : 8, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "r_markdown" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/B26C0956-contents: -------------------------------------------------------------------------------- 1 | # Code Optimisation {#optim} 2 | 3 | ## Compose functions 4 | 5 | ### I want to... 6 | 7 | Write a function that wraps other functions. 8 | 9 | ### Here's how to: 10 | 11 | ```{r} 12 | library(broom) 13 | tidy_lm <- compose(tidy, lm) 14 | tidy_lm(Sepal.Length ~ Species, data = iris) 15 | ``` 16 | 17 | ### Ok, but why? 18 | 19 | `compose(y, x)` composes a function that will do `y(x())`. 20 | 21 | ### See also 22 | 23 | + [A Crazy Little Thing Called {purrr} - Part 5: code optimization](http://colinfay.me/purrr-code-optim/) 24 | 25 | --- 26 | 27 | ## Prefilled functions 28 | 29 | ### I want to... 30 | 31 | Prefill a function so that I won't have to specify the arguments any time I use it. 32 | 33 | ### Here's how to: 34 | 35 | ```{r} 36 | mean_na_rm <- partial(mean, na.rm = TRUE) 37 | mean_na_rm(airquality$Ozone) 38 | ``` 39 | 40 | ### Ok, but why? 41 | 42 | `partial(f, args = "x")` returns a function with a prefilled function with `args = "x"`. 43 | 44 | ### See also 45 | 46 | + [A Crazy Little Thing Called {purrr} - Part 5: code optimization](http://colinfay.me/purrr-code-optim/) 47 | 48 | 49 | --- 50 | 51 | ## Negate a function 52 | 53 | ### I want to... 54 | 55 | Inverse what a function does. 56 | 57 | ### Here's how to: 58 | 59 | ```{r} 60 | is_not_numeric <- negate(is.numeric) 61 | is_not_numeric("this") 62 | ``` 63 | 64 | ### Ok, but why? 65 | 66 | `negate(f)` returns a function that does `!f(...)`. 67 | 68 | ### See also 69 | 70 | --- 71 | 72 | ## Negate a function 73 | 74 | ### I want to... 75 | 76 | Change what input my function can take. 77 | 78 | ### Here's how to: 79 | 80 | ```{r} 81 | lifted_is_na <- lift_ld(is.na) 82 | lifted_is_na(1,2,3,NA) 83 | ``` 84 | 85 | ### Ok, but why? 86 | 87 | The `lift_*` family of functions change the type of input of other function. 88 | 89 | ### See also 90 | 91 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/CC71A08: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516363844234.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "CC71A08", 10 | "lastKnownWriteTime" : 1516398555, 11 | "last_content_update" : 1516398555319, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/_bookdown.yml", 13 | "project_path" : "_bookdown.yml", 14 | "properties" : { 15 | "cursorPosition" : "14,18", 16 | "scrollLine" : "0" 17 | }, 18 | "relative_order" : 6, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "yaml" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/CC71A08-contents: -------------------------------------------------------------------------------- 1 | book_filename: "purrrcookbook" 2 | language: 3 | ui: 4 | chapter_name: "Chapter " 5 | rmd_files: [ 6 | "index.rmd", 7 | "intro.Rmd", 8 | "basics.Rmd", 9 | "statistics.Rmd", 10 | "webmining.Rmd", 11 | "text-wrangling.Rmd", 12 | "code-optim.Rmd", 13 | "data-wrangling.Rmd" 14 | ] 15 | output_dir: "docs" -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/D71ACC7B: -------------------------------------------------------------------------------- 1 | { 2 | "collab_server" : "", 3 | "contents" : "", 4 | "created" : 1516398269811.000, 5 | "dirty" : false, 6 | "encoding" : "UTF-8", 7 | "folds" : "", 8 | "hash" : "0", 9 | "id" : "D71ACC7B", 10 | "lastKnownWriteTime" : 1516398308, 11 | "last_content_update" : 1516398308231, 12 | "path" : "~/Seafile/documents_colin/R/purrrcookbook/intro.Rmd", 13 | "project_path" : "intro.Rmd", 14 | "properties" : { 15 | "cursorPosition" : "55,136", 16 | "scrollLine" : "41" 17 | }, 18 | "relative_order" : 7, 19 | "source_on_save" : false, 20 | "source_window" : "", 21 | "type" : "r_markdown" 22 | } -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/D71ACC7B-contents: -------------------------------------------------------------------------------- 1 | # How to read this book {-} 2 | 3 | This book is divided in `r length(list.files(pattern = "Rmd")) - 4` chapters. 4 | 5 | Each chapter contains a random number of receipes, more or less from the easiest to more complex examples. 6 | 7 | - "Statistics" contains a list of useful common stat tricks with {purrr} 8 | - "Webmining" gives you elements to mine info from the web (HTML / JSON) 9 | - "Text Wrangling" covers some text mining methods 10 | - "Code optimisation" is a chapter about using {purrr} to write better code 11 | - "Data Wrangling" is a list of receipes I couldn't fit anywhere else ¯\\_(ツ)_/¯ 12 | 13 | Based on other programming cookbook template, each receipe is divided as such: 14 | 15 | - "I want to...": what you want to do 16 | - "Here's how to": how to do this 17 | - "Ok, but why?": more explanations about the solution 18 | - "See also": further references if you want to go deeper 19 | 20 | ## Who is this cookbook for? {-} 21 | 22 | Anybody interested in learning more about {purrr}, either by reading this from cover to cover (well... figuratively speaking), of by picking what you find interesting. 23 | 24 | ## Before reading {-} 25 | 26 | We expect the reader to be a little bit familiar with R, and with the core packages from the tidyverse. 27 | 28 | Copy and paste the below code to be sure you have all the packages you need. 29 | 30 | ```{r eval = FALSE} 31 | install.packages("tidyverse") 32 | install.packages("broom") 33 | install.packages("rvest") 34 | install.packages("attempt") 35 | install.packages("tidystringdist") 36 | install.packages("tidytext") 37 | ``` 38 | 39 | Let's launch the tidyverse to be sure we have everything we need: 40 | 41 | ```{r} 42 | library(tidyverse) 43 | ``` 44 | 45 | 46 | ## You want another receipe {-} 47 | 48 | For another receipe, please ask on [this issue](https://github.com/ColinFay/purrr-cookbook/issues/1). 49 | 50 | ## You want to share a receipe {-} 51 | 52 | I'll be glad to add other {purrr} receipes, so if ever you want to share one (or more), feel free to make a PR on the GitHub repo. 53 | 54 | ## What to do if you find a typo {-} 55 | 56 | Nobody's perfect and this book might contains typos. So please, yes please, open a [PR](https://github.com/ColinFay/purrr-cookbook/pulls) (or feel free to reach me on [Twitter](https://twitter.com/_ColinFay)) 57 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/E124C677-contents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/E124C677-contents -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/F29603B4-contents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/F29603B4-contents -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/F4B20051-contents: -------------------------------------------------------------------------------- 1 | #' Coerce a list to a vector 2 | #' 3 | #' `as_vector()` collapses a list of vectors into one vector. It 4 | #' checks that the type of each vector is consistent with 5 | #' `.type`. If the list can not be simplified, it throws an error. 6 | #' `simplify` will simplify a vector if possible; `simplify_all` 7 | #' will apply `simplify` to every element of a list. 8 | #' 9 | #' `.type` can be a vector mold specifying both the type and the 10 | #' length of the vectors to be concatenated, such as `numeric(1)` 11 | #' or `integer(4)`. Alternatively, it can be a string describing 12 | #' the type, one of: "logical", "integer", "double", "complex", 13 | #' "character" or "raw". 14 | #' 15 | #' @param .x A list of vectors 16 | #' @param .type A vector mold or a string describing the type of the 17 | #' input vectors. The latter can be any of the types returned by 18 | #' [typeof()], or "numeric" as a shorthand for either 19 | #' "double" or "integer". 20 | #' @export 21 | #' @examples 22 | #' # Supply the type either with a string: 23 | #' as.list(letters) %>% as_vector("character") 24 | #' 25 | #' # Or with a vector mold: 26 | #' as.list(letters) %>% as_vector(character(1)) 27 | #' 28 | #' # Vector molds are more flexible because they also specify the 29 | #' # length of the concatenated vectors: 30 | #' list(1:2, 3:4, 5:6) %>% as_vector(integer(2)) 31 | #' 32 | #' # Note that unlike vapply(), as_vector() never adds dimension 33 | #' # attributes. So when you specify a vector mold of size > 1, you 34 | #' # always get a vector and not a matrix 35 | as_vector <- function(.x, .type = NULL) { 36 | if (can_simplify(.x, .type)) { 37 | unlist(.x) 38 | } else { 39 | stop("Cannot coerce .x to a vector", call. = FALSE) 40 | } 41 | } 42 | 43 | #' @export 44 | #' @rdname as_vector 45 | simplify <- function(.x, .type = NULL) { 46 | if (can_simplify(.x, .type)) { 47 | unlist(.x) 48 | } else { 49 | .x 50 | } 51 | } 52 | 53 | #' @export 54 | #' @rdname as_vector 55 | simplify_all <- function(.x, .type = NULL) { 56 | map(.x, simplify, .type = .type) 57 | } 58 | 59 | 60 | # Simplify a list of atomic vectors of the same type to a vector 61 | # 62 | # simplify_list(list(1, 2, 3)) 63 | can_simplify <- function(x, type = NULL) { 64 | is_atomic <- vapply(x, is.atomic, logical(1)) 65 | if (!all(is_atomic)) return(FALSE) 66 | 67 | mode <- unique(vapply(x, typeof, character(1))) 68 | if (length(mode) > 1 && 69 | !all(c("double", "integer") %in% mode)) { 70 | return(FALSE) 71 | } 72 | 73 | # This can be coerced safely. If type is supplied, perform 74 | # additional check 75 | is.null(type) || can_coerce(x, type) 76 | } 77 | 78 | can_coerce <- function(x, type) { 79 | actual <- typeof(x[[1]]) 80 | 81 | if (is_mold(type)) { 82 | lengths <- unique(map_int(x, length)) 83 | if (length(lengths) > 1 || !(lengths == length(type))) { 84 | return(FALSE) 85 | } else { 86 | type <- typeof(type) 87 | } 88 | } 89 | 90 | if (actual == "integer" && type %in% c("integer", "double", "numeric")) { 91 | return(TRUE) 92 | } 93 | 94 | if (actual %in% c("integer", "double") && type == "numeric") { 95 | return(TRUE) 96 | } 97 | 98 | actual == type 99 | } 100 | 101 | 102 | # is a mold? As opposed to a string 103 | is_mold <- function(type) { 104 | modes <- c("numeric", "logical", "integer", "double", "complex", 105 | "character", "raw") 106 | length(type) > 1 || (!type %in% modes) 107 | } 108 | -------------------------------------------------------------------------------- /.Rproj.user/5F53E0D7/sources/s-7463A4D5/lock_file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/5F53E0D7/sources/s-7463A4D5/lock_file -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/1CA9621D-webmining/1/5F53E0D76BB710DA/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516365694} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/1CA9621D-webmining/1/5F53E0D77463A4D5/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516380726} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/1CA9621D-webmining/1/5F53E0D7BC5D4DEC/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516363410} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/1CA9621D-webmining/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516380726} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/57726029-intro/1/5F53E0D77463A4D5/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516398276} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/57726029-intro/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516398276} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/95B7313E-basics/1/5F53E0D77463A4D5/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516394742} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/95B7313E-basics/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516394742} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/98AEBD6F-data-wrangling/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516346216} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D74BB9F9B0/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516192451} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D74BED8425/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516134648} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D77463A4D5/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516380579} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D77DF0F42E/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516047537} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D7831C07FE/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516132863} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D788E0BC1D/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516049277} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D78EAAD23E/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516200597} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D797F9E39B/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516291271} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D7A01679E6/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1515795257} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D7B393B584/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516348340} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D7BC5D4DEC/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516348608} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/5F53E0D7FD9F7783/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516134879} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FC61AA20-index/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516380579} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/FF18FE3-code-optim/1/s/chunks.json: -------------------------------------------------------------------------------- 1 | {"chunk_definitions":[],"doc_write_time":1516293291} -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/patch-chunk-names: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/.Rproj.user/shared/notebooks/patch-chunk-names -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/paths: -------------------------------------------------------------------------------- 1 | /Users/colin/Seafile/documents_colin/R/purrr/R/as_mapper.R="9BAC893A" 2 | /Users/colin/Seafile/documents_colin/R/purrr/R/coercion.R="F19C4542" 3 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/README.md="613FA65" 4 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/_bookdown.yml="B6792772" 5 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/_output.yml="B80BC7DB" 6 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/basics.Rmd="95B7313E" 7 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/book.bib="72C61171" 8 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/code-optim.Rmd="FF18FE3" 9 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/data-wrangling.Rmd="98AEBD6F" 10 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/index.Rmd="FC61AA20" 11 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/intro.Rmd="57726029" 12 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/packages.bib="64DE6095" 13 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/purrrcookbook.Rmd="B9F33557" 14 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/skeleton="D4D790EF" 15 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/style.css="DB226454" 16 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/test.json="6B164110" 17 | /Users/colin/Seafile/documents_colin/R/purrrcookbook/webmining.Rmd="1CA9621D" 18 | /Users/colin/Seafile/documents_colin/R/whereshouldwe.R="1BA2E75F" 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## A purrr cookbook 2 | 3 | > Disclaimer: this is still a work in progress 4 | 5 | A series of {purrr} common receipes as a cookbookdown. 6 | 7 | Losely based on a series of [blogposts](http://colinfay.me/tags#purrr), and this [Twitter moment](https://twitter.com/i/moments/950031718521671680). 8 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_book/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-bookdown.css: -------------------------------------------------------------------------------- 1 | .book .book-header h1 { 2 | padding-left: 20px; 3 | padding-right: 20px; 4 | } 5 | .book .book-header.fixed { 6 | position: fixed; 7 | right: 0; 8 | top: 0; 9 | left: 0; 10 | border-bottom: 1px solid rgba(0,0,0,.07); 11 | } 12 | span.search-highlight { 13 | background-color: #ffff88; 14 | } 15 | @media (min-width: 600px) { 16 | .book.with-summary .book-header.fixed { 17 | left: 300px; 18 | } 19 | } 20 | @media (max-width: 1240px) { 21 | .book .book-body.fixed { 22 | top: 50px; 23 | } 24 | .book .book-body.fixed .body-inner { 25 | top: auto; 26 | } 27 | } 28 | @media (max-width: 600px) { 29 | .book.with-summary .book-header.fixed { 30 | left: calc(100% - 60px); 31 | min-width: 300px; 32 | } 33 | .book.with-summary .book-body { 34 | transform: none; 35 | left: calc(100% - 60px); 36 | min-width: 300px; 37 | } 38 | .book .book-body.fixed { 39 | top: 0; 40 | } 41 | } 42 | 43 | .book .book-body.fixed .body-inner { 44 | top: 50px; 45 | } 46 | .book .book-body .page-wrapper .page-inner section.normal sub, .book .book-body .page-wrapper .page-inner section.normal sup { 47 | font-size: 85%; 48 | } 49 | 50 | @media print { 51 | .book .book-summary, .book .book-body .book-header, .fa { 52 | display: none !important; 53 | } 54 | .book .book-body.fixed { 55 | left: 0px; 56 | } 57 | .book .book-body,.book .book-body .body-inner, .book.with-summary { 58 | overflow: visible !important; 59 | } 60 | } 61 | .kable_wrapper { 62 | border-spacing: 20px 0; 63 | border-collapse: separate; 64 | border: none; 65 | margin: auto; 66 | } 67 | .kable_wrapper > tbody > tr > td { 68 | vertical-align: top; 69 | } 70 | .book .book-body .page-wrapper .page-inner section.normal table tr.header { 71 | border-top-width: 2px; 72 | } 73 | .book .book-body .page-wrapper .page-inner section.normal table tr:last-child td { 74 | border-bottom-width: 2px; 75 | } 76 | .book .book-body .page-wrapper .page-inner section.normal table td, .book .book-body .page-wrapper .page-inner section.normal table th { 77 | border-left: none; 78 | border-right: none; 79 | } 80 | .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr, .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr > td { 81 | border-top: none; 82 | } 83 | .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr:last-child > td { 84 | border-bottom: none; 85 | } 86 | 87 | div.theorem, div.lemma, div.corollary, div.proposition { 88 | font-style: italic; 89 | } 90 | span.theorem, span.lemma, span.corollary, span.proposition { 91 | font-style: normal; 92 | } 93 | div.proof:after { 94 | content: "\25a2"; 95 | float: right; 96 | } 97 | .header-section-number { 98 | padding-right: .5em; 99 | } 100 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-fontsettings.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Theme 1 3 | */ 4 | .color-theme-1 .dropdown-menu { 5 | background-color: #111111; 6 | border-color: #7e888b; 7 | } 8 | .color-theme-1 .dropdown-menu .dropdown-caret .caret-inner { 9 | border-bottom: 9px solid #111111; 10 | } 11 | .color-theme-1 .dropdown-menu .buttons { 12 | border-color: #7e888b; 13 | } 14 | .color-theme-1 .dropdown-menu .button { 15 | color: #afa790; 16 | } 17 | .color-theme-1 .dropdown-menu .button:hover { 18 | color: #73553c; 19 | } 20 | /* 21 | * Theme 2 22 | */ 23 | .color-theme-2 .dropdown-menu { 24 | background-color: #2d3143; 25 | border-color: #272a3a; 26 | } 27 | .color-theme-2 .dropdown-menu .dropdown-caret .caret-inner { 28 | border-bottom: 9px solid #2d3143; 29 | } 30 | .color-theme-2 .dropdown-menu .buttons { 31 | border-color: #272a3a; 32 | } 33 | .color-theme-2 .dropdown-menu .button { 34 | color: #62677f; 35 | } 36 | .color-theme-2 .dropdown-menu .button:hover { 37 | color: #f4f4f5; 38 | } 39 | .book .book-header .font-settings .font-enlarge { 40 | line-height: 30px; 41 | font-size: 1.4em; 42 | } 43 | .book .book-header .font-settings .font-reduce { 44 | line-height: 30px; 45 | font-size: 1em; 46 | } 47 | .book.color-theme-1 .book-body { 48 | color: #704214; 49 | background: #f3eacb; 50 | } 51 | .book.color-theme-1 .book-body .page-wrapper .page-inner section { 52 | background: #f3eacb; 53 | } 54 | .book.color-theme-2 .book-body { 55 | color: #bdcadb; 56 | background: #1c1f2b; 57 | } 58 | .book.color-theme-2 .book-body .page-wrapper .page-inner section { 59 | background: #1c1f2b; 60 | } 61 | .book.font-size-0 .book-body .page-inner section { 62 | font-size: 1.2rem; 63 | } 64 | .book.font-size-1 .book-body .page-inner section { 65 | font-size: 1.4rem; 66 | } 67 | .book.font-size-2 .book-body .page-inner section { 68 | font-size: 1.6rem; 69 | } 70 | .book.font-size-3 .book-body .page-inner section { 71 | font-size: 2.2rem; 72 | } 73 | .book.font-size-4 .book-body .page-inner section { 74 | font-size: 4rem; 75 | } 76 | .book.font-family-0 { 77 | font-family: Georgia, serif; 78 | } 79 | .book.font-family-1 { 80 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 81 | } 82 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal { 83 | color: #704214; 84 | } 85 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a { 86 | color: inherit; 87 | } 88 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 89 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2, 90 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3, 91 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4, 92 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5, 93 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 94 | color: inherit; 95 | } 96 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 97 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 { 98 | border-color: inherit; 99 | } 100 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 101 | color: inherit; 102 | } 103 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr { 104 | background-color: inherit; 105 | } 106 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote { 107 | border-color: inherit; 108 | } 109 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, 110 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { 111 | background: #fdf6e3; 112 | color: #657b83; 113 | border-color: #f8df9c; 114 | } 115 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight { 116 | background-color: inherit; 117 | } 118 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th, 119 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td { 120 | border-color: #f5d06c; 121 | } 122 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr { 123 | color: inherit; 124 | background-color: #fdf6e3; 125 | border-color: #444444; 126 | } 127 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 128 | background-color: #fbeecb; 129 | } 130 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal { 131 | color: #bdcadb; 132 | } 133 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a { 134 | color: #3eb1d0; 135 | } 136 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 137 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2, 138 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3, 139 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4, 140 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5, 141 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 142 | color: #fffffa; 143 | } 144 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 145 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 { 146 | border-color: #373b4e; 147 | } 148 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 149 | color: #373b4e; 150 | } 151 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr { 152 | background-color: #373b4e; 153 | } 154 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote { 155 | border-color: #373b4e; 156 | } 157 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, 158 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { 159 | color: #9dbed8; 160 | background: #2d3143; 161 | border-color: #2d3143; 162 | } 163 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight { 164 | background-color: #282a39; 165 | } 166 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th, 167 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td { 168 | border-color: #3b3f54; 169 | } 170 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr { 171 | color: #b6c2d2; 172 | background-color: #2d3143; 173 | border-color: #3b3f54; 174 | } 175 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 176 | background-color: #35394b; 177 | } 178 | .book.color-theme-1 .book-header { 179 | color: #afa790; 180 | background: transparent; 181 | } 182 | .book.color-theme-1 .book-header .btn { 183 | color: #afa790; 184 | } 185 | .book.color-theme-1 .book-header .btn:hover { 186 | color: #73553c; 187 | background: none; 188 | } 189 | .book.color-theme-1 .book-header h1 { 190 | color: #704214; 191 | } 192 | .book.color-theme-2 .book-header { 193 | color: #7e888b; 194 | background: transparent; 195 | } 196 | .book.color-theme-2 .book-header .btn { 197 | color: #3b3f54; 198 | } 199 | .book.color-theme-2 .book-header .btn:hover { 200 | color: #fffff5; 201 | background: none; 202 | } 203 | .book.color-theme-2 .book-header h1 { 204 | color: #bdcadb; 205 | } 206 | .book.color-theme-1 .book-body .navigation { 207 | color: #afa790; 208 | } 209 | .book.color-theme-1 .book-body .navigation:hover { 210 | color: #73553c; 211 | } 212 | .book.color-theme-2 .book-body .navigation { 213 | color: #383f52; 214 | } 215 | .book.color-theme-2 .book-body .navigation:hover { 216 | color: #fffff5; 217 | } 218 | /* 219 | * Theme 1 220 | */ 221 | .book.color-theme-1 .book-summary { 222 | color: #afa790; 223 | background: #111111; 224 | border-right: 1px solid rgba(0, 0, 0, 0.07); 225 | } 226 | .book.color-theme-1 .book-summary .book-search { 227 | background: transparent; 228 | } 229 | .book.color-theme-1 .book-summary .book-search input, 230 | .book.color-theme-1 .book-summary .book-search input:focus { 231 | border: 1px solid transparent; 232 | } 233 | .book.color-theme-1 .book-summary ul.summary li.divider { 234 | background: #7e888b; 235 | box-shadow: none; 236 | } 237 | .book.color-theme-1 .book-summary ul.summary li i.fa-check { 238 | color: #33cc33; 239 | } 240 | .book.color-theme-1 .book-summary ul.summary li.done > a { 241 | color: #877f6a; 242 | } 243 | .book.color-theme-1 .book-summary ul.summary li a, 244 | .book.color-theme-1 .book-summary ul.summary li span { 245 | color: #877f6a; 246 | background: transparent; 247 | font-weight: normal; 248 | } 249 | .book.color-theme-1 .book-summary ul.summary li.active > a, 250 | .book.color-theme-1 .book-summary ul.summary li a:hover { 251 | color: #704214; 252 | background: transparent; 253 | font-weight: normal; 254 | } 255 | /* 256 | * Theme 2 257 | */ 258 | .book.color-theme-2 .book-summary { 259 | color: #bcc1d2; 260 | background: #2d3143; 261 | border-right: none; 262 | } 263 | .book.color-theme-2 .book-summary .book-search { 264 | background: transparent; 265 | } 266 | .book.color-theme-2 .book-summary .book-search input, 267 | .book.color-theme-2 .book-summary .book-search input:focus { 268 | border: 1px solid transparent; 269 | } 270 | .book.color-theme-2 .book-summary ul.summary li.divider { 271 | background: #272a3a; 272 | box-shadow: none; 273 | } 274 | .book.color-theme-2 .book-summary ul.summary li i.fa-check { 275 | color: #33cc33; 276 | } 277 | .book.color-theme-2 .book-summary ul.summary li.done > a { 278 | color: #62687f; 279 | } 280 | .book.color-theme-2 .book-summary ul.summary li a, 281 | .book.color-theme-2 .book-summary ul.summary li span { 282 | color: #c1c6d7; 283 | background: transparent; 284 | font-weight: 600; 285 | } 286 | .book.color-theme-2 .book-summary ul.summary li.active > a, 287 | .book.color-theme-2 .book-summary ul.summary li a:hover { 288 | color: #f4f4f5; 289 | background: #252737; 290 | font-weight: 600; 291 | } 292 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-search.css: -------------------------------------------------------------------------------- 1 | .book .book-summary .book-search { 2 | padding: 6px; 3 | background: transparent; 4 | position: absolute; 5 | top: -50px; 6 | left: 0px; 7 | right: 0px; 8 | transition: top 0.5s ease; 9 | } 10 | .book .book-summary .book-search input, 11 | .book .book-summary .book-search input:focus, 12 | .book .book-summary .book-search input:hover { 13 | width: 100%; 14 | background: transparent; 15 | border: 1px solid #ccc; 16 | box-shadow: none; 17 | outline: none; 18 | line-height: 22px; 19 | padding: 7px 4px; 20 | color: inherit; 21 | box-sizing: border-box; 22 | } 23 | .book.with-search .book-summary .book-search { 24 | top: 0px; 25 | } 26 | .book.with-search .book-summary ul.summary { 27 | top: 50px; 28 | } 29 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["jQuery"], function(jQuery) { 2 | 3 | /* 4 | * jQuery Highlight plugin 5 | * 6 | * Based on highlight v3 by Johann Burkard 7 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 8 | * 9 | * Code a little bit refactored and cleaned (in my humble opinion). 10 | * Most important changes: 11 | * - has an option to highlight only entire words (wordsOnly - false by default), 12 | * - has an option to be case sensitive (caseSensitive - false by default) 13 | * - highlight element tag and class names can be specified in options 14 | * 15 | * Copyright (c) 2009 Bartek Szopka 16 | * 17 | * Licensed under MIT license. 18 | * 19 | */ 20 | 21 | jQuery.extend({ 22 | highlight: function (node, re, nodeName, className) { 23 | if (node.nodeType === 3) { 24 | var match = node.data.match(re); 25 | if (match) { 26 | var highlight = document.createElement(nodeName || 'span'); 27 | highlight.className = className || 'highlight'; 28 | var wordNode = node.splitText(match.index); 29 | wordNode.splitText(match[0].length); 30 | var wordClone = wordNode.cloneNode(true); 31 | highlight.appendChild(wordClone); 32 | wordNode.parentNode.replaceChild(highlight, wordNode); 33 | return 1; //skip added node in parent 34 | } 35 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 36 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 37 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 38 | for (var i = 0; i < node.childNodes.length; i++) { 39 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 40 | } 41 | } 42 | return 0; 43 | } 44 | }); 45 | 46 | jQuery.fn.unhighlight = function (options) { 47 | var settings = { className: 'highlight', element: 'span' }; 48 | jQuery.extend(settings, options); 49 | 50 | return this.find(settings.element + "." + settings.className).each(function () { 51 | var parent = this.parentNode; 52 | parent.replaceChild(this.firstChild, this); 53 | parent.normalize(); 54 | }).end(); 55 | }; 56 | 57 | jQuery.fn.highlight = function (words, options) { 58 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 59 | jQuery.extend(settings, options); 60 | 61 | if (words.constructor === String) { 62 | words = [words]; 63 | } 64 | words = jQuery.grep(words, function(word, i){ 65 | return word !== ''; 66 | }); 67 | words = jQuery.map(words, function(word, i) { 68 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 69 | }); 70 | if (words.length === 0) { return this; } 71 | 72 | var flag = settings.caseSensitive ? "" : "i"; 73 | var pattern = "(" + words.join("|") + ")"; 74 | if (settings.wordsOnly) { 75 | pattern = "\\b" + pattern + "\\b"; 76 | } 77 | var re = new RegExp(pattern, flag); 78 | 79 | return this.each(function () { 80 | jQuery.highlight(this, re, settings.element, settings.className); 81 | }); 82 | }; 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/lunr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 3 | * Copyright (C) 2015 Oliver Nightingale 4 | * MIT Licensed 5 | * @license 6 | */ 7 | !function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-\/]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n's that are truncated 95 | $('a').each(function(i, el) { 96 | if (el.offsetWidth >= el.scrollWidth) return; 97 | if (typeof el.title === 'undefined') return; 98 | el.title = el.text; 99 | }); 100 | 101 | // restore TOC scroll position 102 | var pos = gs.get('tocScrollTop'); 103 | if (typeof pos !== 'undefined') summary.scrollTop(pos); 104 | 105 | // highlight the TOC item that has same text as the heading in view as scrolling 106 | if (toc && toc.scroll_highlight !== false) (function() { 107 | // scroll the current TOC item into viewport 108 | var ht = $(window).height(), rect = li[0].getBoundingClientRect(); 109 | if (rect.top >= ht || rect.top <= 0 || rect.bottom <= 0) { 110 | summary.scrollTop(li[0].offsetTop); 111 | } 112 | // current chapter TOC items 113 | var items = $('a[href^="' + href + '"]').parent('li.chapter'), 114 | m = items.length; 115 | if (m === 0) { 116 | items = summary.find('li.chapter'); 117 | m = items.length; 118 | } 119 | if (m === 0) return; 120 | // all section titles on current page 121 | var hs = bookInner.find('.page-inner').find('h1,h2,h3'), n = hs.length, 122 | ts = hs.map(function(i, el) { return $(el).text(); }); 123 | if (n === 0) return; 124 | var scrollHandler = function(e) { 125 | var ht = $(window).height(); 126 | clearTimeout($.data(this, 'scrollTimer')); 127 | $.data(this, 'scrollTimer', setTimeout(function() { 128 | // find the first visible title in the viewport 129 | for (var i = 0; i < n; i++) { 130 | var rect = hs[i].getBoundingClientRect(); 131 | if (rect.top >= 0 && rect.bottom <= ht) break; 132 | } 133 | if (i === n) return; 134 | items.removeClass('active'); 135 | for (var j = 0; j < m; j++) { 136 | if (items.eq(j).children('a').first().text() === ts[i]) break; 137 | } 138 | if (j === m) j = 0; // highlight the chapter title 139 | // search bottom-up for a visible TOC item to highlight; if an item is 140 | // hidden, we check if its parent is visible, and so on 141 | while (j > 0 && items.eq(j).is(':hidden')) j--; 142 | items.eq(j).addClass('active'); 143 | }, 250)); 144 | }; 145 | bookInner.on('scroll.bookdown', scrollHandler); 146 | bookBody.on('scroll.bookdown', scrollHandler); 147 | })(); 148 | 149 | // do not refresh the page if the TOC item points to the current page 150 | $('a[href="' + href + '"]').parent('li.chapter').children('a') 151 | .on('click', function(e) { 152 | bookInner.scrollTop(0); 153 | bookBody.scrollTop(0); 154 | return false; 155 | }); 156 | 157 | var toolbar = config.toolbar; 158 | if (!toolbar || toolbar.position !== 'static') { 159 | var bookHeader = $('.book-header'); 160 | bookBody.addClass('fixed'); 161 | bookHeader.addClass('fixed') 162 | .css('background-color', bookBody.css('background-color')) 163 | .on('click.bookdown', function(e) { 164 | // the theme may have changed after user clicks the theme button 165 | bookHeader.css('background-color', bookBody.css('background-color')); 166 | }); 167 | } 168 | 169 | }); 170 | 171 | gitbook.events.bind("page.change", function(e) { 172 | // store TOC scroll position 173 | var summary = $('ul.summary'); 174 | gs.set('tocScrollTop', summary.scrollTop()); 175 | }); 176 | 177 | var bookBody = $('.book-body'), bookInner = bookBody.find('.body-inner'); 178 | var chapterTitle = function() { 179 | return bookInner.find('.page-inner').find('h1,h2').first().text(); 180 | }; 181 | var bookTitle = function() { 182 | return bookInner.find('.book-header > h1').first().text(); 183 | }; 184 | var saveScrollPos = function(e) { 185 | // save scroll position before page is reloaded 186 | gs.set('bodyScrollTop', { 187 | body: bookBody.scrollTop(), 188 | inner: bookInner.scrollTop(), 189 | focused: document.hasFocus(), 190 | title: chapterTitle() 191 | }); 192 | }; 193 | $(document).on('servr:reload', saveScrollPos); 194 | 195 | // check if the page is loaded in an iframe (e.g. the RStudio preview window) 196 | var inIFrame = function() { 197 | var inIframe = true; 198 | try { inIframe = window.self !== window.top; } catch (e) {} 199 | return inIframe; 200 | }; 201 | $(window).on('blur unload', function(e) { 202 | if (inIFrame()) saveScrollPos(e); 203 | gs.set('bookTitle', bookTitle()); 204 | }); 205 | 206 | $(function(e) { 207 | if (gs.get('bookTitle', '') !== bookTitle()) localStorage.clear(); 208 | var pos = gs.get('bodyScrollTop'); 209 | if (pos) { 210 | if (pos.title === chapterTitle()) { 211 | if (pos.body !== 0) bookBody.scrollTop(pos.body); 212 | if (pos.inner !== 0) bookInner.scrollTop(pos.inner); 213 | } 214 | if (pos.focused) bookInner.find('.page-wrapper').focus(); 215 | } 216 | // clear book body scroll position 217 | gs.remove('bodyScrollTop'); 218 | }); 219 | 220 | }); 221 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/plugin-fontsettings.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var fontState; 3 | 4 | var THEMES = { 5 | "white": 0, 6 | "sepia": 1, 7 | "night": 2 8 | }; 9 | 10 | var FAMILY = { 11 | "serif": 0, 12 | "sans": 1 13 | }; 14 | 15 | // Save current font settings 16 | function saveFontSettings() { 17 | gitbook.storage.set("fontState", fontState); 18 | update(); 19 | } 20 | 21 | // Increase font size 22 | function enlargeFontSize(e) { 23 | e.preventDefault(); 24 | if (fontState.size >= 4) return; 25 | 26 | fontState.size++; 27 | saveFontSettings(); 28 | }; 29 | 30 | // Decrease font size 31 | function reduceFontSize(e) { 32 | e.preventDefault(); 33 | if (fontState.size <= 0) return; 34 | 35 | fontState.size--; 36 | saveFontSettings(); 37 | }; 38 | 39 | // Change font family 40 | function changeFontFamily(index, e) { 41 | e.preventDefault(); 42 | 43 | fontState.family = index; 44 | saveFontSettings(); 45 | }; 46 | 47 | // Change type of color 48 | function changeColorTheme(index, e) { 49 | e.preventDefault(); 50 | 51 | var $book = $(".book"); 52 | 53 | if (fontState.theme !== 0) 54 | $book.removeClass("color-theme-"+fontState.theme); 55 | 56 | fontState.theme = index; 57 | if (fontState.theme !== 0) 58 | $book.addClass("color-theme-"+fontState.theme); 59 | 60 | saveFontSettings(); 61 | }; 62 | 63 | function update() { 64 | var $book = gitbook.state.$book; 65 | 66 | $(".font-settings .font-family-list li").removeClass("active"); 67 | $(".font-settings .font-family-list li:nth-child("+(fontState.family+1)+")").addClass("active"); 68 | 69 | $book[0].className = $book[0].className.replace(/\bfont-\S+/g, ''); 70 | $book.addClass("font-size-"+fontState.size); 71 | $book.addClass("font-family-"+fontState.family); 72 | 73 | if(fontState.theme !== 0) { 74 | $book[0].className = $book[0].className.replace(/\bcolor-theme-\S+/g, ''); 75 | $book.addClass("color-theme-"+fontState.theme); 76 | } 77 | }; 78 | 79 | function init(config) { 80 | var $bookBody, $book; 81 | 82 | //Find DOM elements. 83 | $book = gitbook.state.$book; 84 | $bookBody = $book.find(".book-body"); 85 | 86 | // Instantiate font state object 87 | fontState = gitbook.storage.get("fontState", { 88 | size: config.size || 2, 89 | family: FAMILY[config.family || "sans"], 90 | theme: THEMES[config.theme || "white"] 91 | }); 92 | 93 | update(); 94 | }; 95 | 96 | 97 | gitbook.events.bind("start", function(e, config) { 98 | var opts = config.fontsettings; 99 | 100 | // Create buttons in toolbar 101 | gitbook.toolbar.createButton({ 102 | icon: 'fa fa-font', 103 | label: 'Font Settings', 104 | className: 'font-settings', 105 | dropdown: [ 106 | [ 107 | { 108 | text: 'A', 109 | className: 'font-reduce', 110 | onClick: reduceFontSize 111 | }, 112 | { 113 | text: 'A', 114 | className: 'font-enlarge', 115 | onClick: enlargeFontSize 116 | } 117 | ], 118 | [ 119 | { 120 | text: 'Serif', 121 | onClick: _.partial(changeFontFamily, 0) 122 | }, 123 | { 124 | text: 'Sans', 125 | onClick: _.partial(changeFontFamily, 1) 126 | } 127 | ], 128 | [ 129 | { 130 | text: 'White', 131 | onClick: _.partial(changeColorTheme, 0) 132 | }, 133 | { 134 | text: 'Sepia', 135 | onClick: _.partial(changeColorTheme, 1) 136 | }, 137 | { 138 | text: 'Night', 139 | onClick: _.partial(changeColorTheme, 2) 140 | } 141 | ] 142 | ] 143 | }); 144 | 145 | 146 | // Init current settings 147 | init(opts); 148 | }); 149 | }); 150 | 151 | 152 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/plugin-search.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var index = null; 3 | var $searchInput, $searchForm; 4 | var $highlighted, hi = 0, hiOpts = { className: 'search-highlight' }; 5 | var collapse = false; 6 | 7 | // Use a specific index 8 | function loadIndex(data) { 9 | // [Yihui] In bookdown, I use a character matrix to store the chapter 10 | // content, and the index is dynamically built on the client side. 11 | // Gitbook prebuilds the index data instead: https://github.com/GitbookIO/plugin-search 12 | // We can certainly do that via R packages V8 and jsonlite, but let's 13 | // see how slow it really is before improving it. On the other hand, 14 | // lunr cannot handle non-English text very well, e.g. the default 15 | // tokenizer cannot deal with Chinese text, so we may want to replace 16 | // lunr with a dumb simple text matching approach. 17 | index = lunr(function () { 18 | this.ref('url'); 19 | this.field('title', { boost: 10 }); 20 | this.field('body'); 21 | }); 22 | data.map(function(item) { 23 | index.add({ 24 | url: item[0], 25 | title: item[1], 26 | body: item[2] 27 | }); 28 | }); 29 | } 30 | 31 | // Fetch the search index 32 | function fetchIndex() { 33 | return $.getJSON(gitbook.state.basePath+"/search_index.json") 34 | .then(loadIndex); // [Yihui] we need to use this object later 35 | } 36 | 37 | // Search for a term and return results 38 | function search(q) { 39 | if (!index) return; 40 | 41 | var results = _.chain(index.search(q)) 42 | .map(function(result) { 43 | var parts = result.ref.split("#"); 44 | return { 45 | path: parts[0], 46 | hash: parts[1] 47 | }; 48 | }) 49 | .value(); 50 | 51 | // [Yihui] Highlight the search keyword on current page 52 | hi = 0; 53 | $highlighted = results.length === 0 ? undefined : $('.page-inner') 54 | .unhighlight(hiOpts).highlight(q, hiOpts).find('span.search-highlight'); 55 | scrollToHighlighted(); 56 | toggleTOC(results.length > 0); 57 | 58 | return results; 59 | } 60 | 61 | // [Yihui] Scroll the chapter body to the i-th highlighted string 62 | function scrollToHighlighted() { 63 | if (!$highlighted) return; 64 | var n = $highlighted.length; 65 | if (n === 0) return; 66 | var $p = $highlighted.eq(hi), p = $p[0], rect = p.getBoundingClientRect(); 67 | if (rect.top < 0 || rect.bottom > $(window).height()) { 68 | ($(window).width() >= 1240 ? $('.body-inner') : $('.book-body')) 69 | .scrollTop(p.offsetTop - 100); 70 | } 71 | $highlighted.css('background-color', ''); 72 | // an orange background color on the current item and removed later 73 | $p.css('background-color', 'orange'); 74 | setTimeout(function() { 75 | $p.css('background-color', ''); 76 | }, 2000); 77 | } 78 | 79 | // [Yihui] Expand/collapse TOC 80 | function toggleTOC(show) { 81 | if (!collapse) return; 82 | var toc_sub = $('ul.summary').children('li[data-level]').children('ul'); 83 | if (show) return toc_sub.show(); 84 | var href = window.location.pathname; 85 | href = href.substr(href.lastIndexOf('/') + 1); 86 | if (href === '') href = 'index.html'; 87 | var li = $('a[href^="' + href + location.hash + '"]').parent('li.chapter').first(); 88 | toc_sub.hide().parent().has(li).children('ul').show(); 89 | li.children('ul').show(); 90 | } 91 | 92 | // Create search form 93 | function createForm(value) { 94 | if ($searchForm) $searchForm.remove(); 95 | if ($searchInput) $searchInput.remove(); 96 | 97 | $searchForm = $('
    ', { 98 | 'class': 'book-search', 99 | 'role': 'search' 100 | }); 101 | 102 | $searchInput = $('', { 103 | 'type': 'search', 104 | 'class': 'form-control', 105 | 'val': value, 106 | 'placeholder': 'Type to search' 107 | }); 108 | 109 | $searchInput.appendTo($searchForm); 110 | $searchForm.prependTo(gitbook.state.$book.find('.book-summary')); 111 | } 112 | 113 | // Return true if search is open 114 | function isSearchOpen() { 115 | return gitbook.state.$book.hasClass("with-search"); 116 | } 117 | 118 | // Toggle the search 119 | function toggleSearch(_state) { 120 | if (isSearchOpen() === _state) return; 121 | if (!$searchInput) return; 122 | 123 | gitbook.state.$book.toggleClass("with-search", _state); 124 | 125 | // If search bar is open: focus input 126 | if (isSearchOpen()) { 127 | gitbook.sidebar.toggle(true); 128 | $searchInput.focus(); 129 | } else { 130 | $searchInput.blur(); 131 | $searchInput.val(""); 132 | gitbook.storage.remove("keyword"); 133 | gitbook.sidebar.filter(null); 134 | $('.page-inner').unhighlight(hiOpts); 135 | toggleTOC(false); 136 | } 137 | } 138 | 139 | // Recover current search when page changed 140 | function recoverSearch() { 141 | var keyword = gitbook.storage.get("keyword", ""); 142 | 143 | createForm(keyword); 144 | 145 | if (keyword.length > 0) { 146 | if(!isSearchOpen()) { 147 | toggleSearch(true); // [Yihui] open the search box 148 | } 149 | gitbook.sidebar.filter(_.pluck(search(keyword), "path")); 150 | } 151 | } 152 | 153 | 154 | gitbook.events.bind("start", function(e, config) { 155 | // [Yihui] disable search 156 | if (config.search === false) return; 157 | collapse = !config.toc || config.toc.collapse === 'section' || 158 | config.toc.collapse === 'subsection'; 159 | 160 | // Pre-fetch search index and create the form 161 | fetchIndex() 162 | // [Yihui] recover search after the page is loaded 163 | .then(recoverSearch); 164 | 165 | 166 | // Type in search bar 167 | $(document).on("keyup", ".book-search input", function(e) { 168 | var key = (e.keyCode ? e.keyCode : e.which); 169 | // [Yihui] Escape -> close search box; Up/Down: previous/next highlighted 170 | if (key == 27) { 171 | e.preventDefault(); 172 | toggleSearch(false); 173 | } else if (key == 38) { 174 | if (hi <= 0 && $highlighted) hi = $highlighted.length; 175 | hi--; 176 | scrollToHighlighted(); 177 | } else if (key == 40) { 178 | hi++; 179 | if ($highlighted && hi >= $highlighted.length) hi = 0; 180 | scrollToHighlighted(); 181 | } 182 | }).on("input", ".book-search input", function(e) { 183 | var q = $(this).val().trim(); 184 | if (q.length === 0) { 185 | gitbook.sidebar.filter(null); 186 | gitbook.storage.remove("keyword"); 187 | $('.page-inner').unhighlight(hiOpts); 188 | toggleTOC(false); 189 | } else { 190 | var results = search(q); 191 | gitbook.sidebar.filter( 192 | _.pluck(results, "path") 193 | ); 194 | gitbook.storage.set("keyword", q); 195 | } 196 | }); 197 | 198 | // Create the toggle search button 199 | gitbook.toolbar.createButton({ 200 | icon: 'fa fa-search', 201 | label: 'Search', 202 | position: 'left', 203 | onClick: toggleSearch 204 | }); 205 | 206 | // Bind keyboard to toggle search 207 | gitbook.keyboard.bind(['f'], toggleSearch); 208 | }); 209 | 210 | // [Yihui] do not try to recover search; always start fresh 211 | // gitbook.events.bind("page.change", recoverSearch); 212 | }); 213 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/plugin-sharing.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var SITES = { 3 | 'github': { 4 | 'label': 'Github', 5 | 'icon': 'fa fa-github', 6 | 'onClick': function(e) { 7 | e.preventDefault(); 8 | var repo = $('meta[name="github-repo"]').attr('content'); 9 | if (typeof repo === 'undefined') throw("Github repo not defined"); 10 | window.open("https://github.com/"+repo); 11 | } 12 | }, 13 | 'facebook': { 14 | 'label': 'Facebook', 15 | 'icon': 'fa fa-facebook', 16 | 'onClick': function(e) { 17 | e.preventDefault(); 18 | window.open("http://www.facebook.com/sharer/sharer.php?s=100&p[url]="+encodeURIComponent(location.href)); 19 | } 20 | }, 21 | 'twitter': { 22 | 'label': 'Twitter', 23 | 'icon': 'fa fa-twitter', 24 | 'onClick': function(e) { 25 | e.preventDefault(); 26 | window.open("http://twitter.com/home?status="+encodeURIComponent(document.title+" "+location.href)); 27 | } 28 | }, 29 | 'google': { 30 | 'label': 'Google+', 31 | 'icon': 'fa fa-google-plus', 32 | 'onClick': function(e) { 33 | e.preventDefault(); 34 | window.open("https://plus.google.com/share?url="+encodeURIComponent(location.href)); 35 | } 36 | }, 37 | 'weibo': { 38 | 'label': 'Weibo', 39 | 'icon': 'fa fa-weibo', 40 | 'onClick': function(e) { 41 | e.preventDefault(); 42 | window.open("http://service.weibo.com/share/share.php?content=utf-8&url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title)); 43 | } 44 | }, 45 | 'instapaper': { 46 | 'label': 'Instapaper', 47 | 'icon': 'fa fa-instapaper', 48 | 'onClick': function(e) { 49 | e.preventDefault(); 50 | window.open("http://www.instapaper.com/text?u="+encodeURIComponent(location.href)); 51 | } 52 | }, 53 | 'vk': { 54 | 'label': 'VK', 55 | 'icon': 'fa fa-vk', 56 | 'onClick': function(e) { 57 | e.preventDefault(); 58 | window.open("http://vkontakte.ru/share.php?url="+encodeURIComponent(location.href)); 59 | } 60 | } 61 | }; 62 | 63 | 64 | 65 | gitbook.events.bind("start", function(e, config) { 66 | var opts = config.sharing; 67 | if (!opts) return; 68 | 69 | // Create dropdown menu 70 | var menu = _.chain(opts.all) 71 | .map(function(id) { 72 | var site = SITES[id]; 73 | 74 | return { 75 | text: site.label, 76 | onClick: site.onClick 77 | }; 78 | }) 79 | .compact() 80 | .value(); 81 | 82 | // Create main button with dropdown 83 | if (menu.length > 0) { 84 | gitbook.toolbar.createButton({ 85 | icon: 'fa fa-share-alt', 86 | label: 'Share', 87 | position: 'right', 88 | dropdown: [menu] 89 | }); 90 | } 91 | 92 | // Direct actions to share 93 | _.each(SITES, function(site, sideId) { 94 | if (!opts[sideId]) return; 95 | 96 | gitbook.toolbar.createButton({ 97 | icon: site.icon, 98 | label: site.text, 99 | position: 'right', 100 | onClick: site.onClick 101 | }); 102 | }); 103 | }); 104 | }); 105 | -------------------------------------------------------------------------------- /_book/purrr_hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_book/purrr_hex.png -------------------------------------------------------------------------------- /_book/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_book/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /_book/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_book/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png -------------------------------------------------------------------------------- /_book/style.css: -------------------------------------------------------------------------------- 1 | p.caption { 2 | color: #777; 3 | margin-top: 10px; 4 | } 5 | p code { 6 | white-space: inherit; 7 | } 8 | pre { 9 | word-break: normal; 10 | word-wrap: normal; 11 | } 12 | pre code { 13 | white-space: inherit; 14 | } 15 | -------------------------------------------------------------------------------- /_bookdown.yml: -------------------------------------------------------------------------------- 1 | book_filename: "purrrcookbook" 2 | language: 3 | ui: 4 | chapter_name: "Chapter " 5 | rmd_files: [ 6 | "index.rmd", 7 | "intro.Rmd", 8 | "basics.Rmd", 9 | "statistics.Rmd", 10 | "webmining.Rmd", 11 | "text-wrangling.Rmd", 12 | "code-optim.Rmd", 13 | "data-wrangling.Rmd" 14 | ] 15 | output_dir: "docs" -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-10-2.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-12-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-12-2.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-6-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-6-2.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-9-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/_bookdown_files/purrrcookbook_files/figure-html/unnamed-chunk-9-2.png -------------------------------------------------------------------------------- /_output.yml: -------------------------------------------------------------------------------- 1 | bookdown::pdf_book: 2 | includes: 3 | in_header: preamble.tex 4 | latex_engine: xelatex 5 | citation_package: natbib 6 | keep_tex: yes 7 | bookdown::epub_book: default 8 | bookdown::gitbook: 9 | css: style.css 10 | df_print: kable 11 | config: 12 | toc: 13 | collapse: section 14 | before: | 15 |
  • A purrr cookbook
  • 16 | after: | 17 |
  • Written by Colin Fay
  • 18 |
  • Published with bookdown
  • 19 |
  • Hosted on Github
  • 20 | -------------------------------------------------------------------------------- /a.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "066062", 4 | "name": "Observatory Hill", 5 | "label": "Sydney City", 6 | "tz": "Australia/Sydney", 7 | "record_start": "1910", 8 | "record_end": "2017" 9 | }, 10 | { 11 | "id": "067105", 12 | "name": "Richmond RAAF", 13 | "label": "Sydney West", 14 | "tz": "Australia/Sydney", 15 | "record_start": "1939", 16 | "record_end": "2017" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /basics.Rmd: -------------------------------------------------------------------------------- 1 | # purrr basics {#intro} 2 | 3 | ```{r echo = FALSE} 4 | library(purrr) 5 | ``` 6 | 7 | ## map function 8 | 9 | ### I want to... 10 | 11 | Start using {purrr}. 12 | 13 | ### Here's how to: 14 | 15 | The base skeleton of {purrr} iteration functions are: 16 | 17 | ```{r eval = FALSE} 18 | library(purrr) 19 | map(.x, .f, ...) 20 | ``` 21 | 22 | ### Ok, but why? 23 | 24 | In this skeleton: 25 | 26 | + `.x` is a list, a data.frame or a vector. 27 | + `.f` is the function, formula or atomic vector that will be applied on each element of `.f`. 28 | 29 | Here, what `map` does is applying the function to each element of a list. The returned object is always a list. 30 | 31 | ### See also 32 | 33 | + [A introduction to purrr](https://github.com/cwickham/purrr-tutorial) 34 | 35 | --- 36 | 37 | ## map_* functions 38 | 39 | ### I want to... 40 | 41 | Control the output of my iterations. 42 | 43 | ### Here's how to: 44 | 45 | ```{r} 46 | # Returns a dbl 47 | map_dbl(1:10, sqrt) 48 | ``` 49 | 50 | ### Ok, but why? 51 | 52 | You can control the output of your map with these functions: `map_lgl` `map_chr` `map_int` `map_dbl` `map_dfr` `map_dfc`. 53 | 54 | ### See also 55 | 56 | + [R for Data Science - 21.5 The map functions](http://r4ds.had.co.nz/iteration.html#the-map-functions) 57 | 58 | --- 59 | 60 | ## Mappers 61 | 62 | ### I want to... 63 | 64 | Create a function on the fly. 65 | 66 | ### Here's how to: 67 | 68 | ```{r} 69 | map_dbl(1:10, ~ .x + 2) 70 | ``` 71 | 72 | ### Ok, but why? 73 | 74 | One sided formulaes, also called mappers, can be created as the `.f` argument of map. It is build with `~`, then `.x` refers to the element of the list in `.x`. 75 | 76 | When mapping on two elements, you can use `.x` and `.y`. With more than two elements, refer to them with `..1`, `..2`, `..3`, etc. 77 | 78 | ### See also 79 | 80 | + [R for Data Science - 21.5.1 Shortcuts](http://r4ds.had.co.nz/iteration.html#shortcuts) 81 | 82 | --- 83 | 84 | ## map on 2 elements 85 | 86 | ### I want to... 87 | 88 | map over two lists. 89 | 90 | ### Here's how to: 91 | 92 | ```{r} 93 | map2_chr(letters, LETTERS, paste) 94 | ``` 95 | 96 | ### Ok, but why? 97 | 98 | `map2` and friends (`map2` `map2_lgl` `map2_int` `map2_dbl` `map2_chr` `map2_dfr` `map2_dfc`) allows to map over two elements. 99 | 100 | ### See also 101 | 102 | + [R for Data Science - 21.7 Mapping over multiple arguments](http://r4ds.had.co.nz/iteration.html#dealing-with-failure) 103 | 104 | --- 105 | 106 | ## map on more elements 107 | 108 | ### I want to... 109 | 110 | map over more than two lists. 111 | 112 | ### Here's how to: 113 | 114 | ```{r} 115 | l <- list(a = 1:3, b = 2:4, c = 3:5) 116 | pmap_dbl(l, ~ ..1 + ..2 + ..3) 117 | ``` 118 | 119 | ### Ok, but why? 120 | 121 | `pmap` and friends (`pmap_lgl` `pmap_int` `pmap_dbl` `pmap_chr` `pmap_dfr` `pmap_dfc`) allows to map over more than two elements. 122 | 123 | ### See also 124 | 125 | + [R for Data Science - 21.7 Mapping over multiple arguments](http://r4ds.had.co.nz/iteration.html#mapping-over-multiple-arguments) 126 | 127 | --- 128 | 129 | ## Iteration for side effect 130 | 131 | ### I want to... 132 | 133 | Iterate only for side effect. 134 | 135 | ### Here's how to: 136 | 137 | ```{r} 138 | walk(1:2, plot) 139 | ``` 140 | 141 | ### Ok, but why? 142 | 143 | `walk` is the silent conterpart of map, but invisible: you call it just for side effects. `map_*`, `map2_*`, `pwalk` and friends also exists. 144 | 145 | ### See also 146 | 147 | + [R for Data Science - 21.8 Walk](http://r4ds.had.co.nz/iteration.html#walk) 148 | -------------------------------------------------------------------------------- /book.bib: -------------------------------------------------------------------------------- 1 | @Book{xie2015, 2 | title = {Dynamic Documents with {R} and knitr}, 3 | author = {Yihui Xie}, 4 | publisher = {Chapman and Hall/CRC}, 5 | address = {Boca Raton, Florida}, 6 | year = {2015}, 7 | edition = {2nd}, 8 | note = {ISBN 978-1498716963}, 9 | url = {http://yihui.name/knitr/}, 10 | } 11 | -------------------------------------------------------------------------------- /code-optim.Rmd: -------------------------------------------------------------------------------- 1 | # Code Optimisation {#optim} 2 | 3 | ## Compose functions 4 | 5 | ### I want to... 6 | 7 | Write a function that wraps other functions. 8 | 9 | ### Here's how to: 10 | 11 | ```{r} 12 | library(broom) 13 | tidy_lm <- compose(tidy, lm) 14 | tidy_lm(Sepal.Length ~ Species, data = iris) 15 | ``` 16 | 17 | ### Ok, but why? 18 | 19 | `compose(y, x)` composes a function that will do `y(x())`. 20 | 21 | ### See also 22 | 23 | + [A Crazy Little Thing Called {purrr} - Part 5: code optimization](http://colinfay.me/purrr-code-optim/) 24 | 25 | --- 26 | 27 | ## Prefilled functions 28 | 29 | ### I want to... 30 | 31 | Prefill a function so that I won't have to specify the arguments any time I use it. 32 | 33 | ### Here's how to: 34 | 35 | ```{r} 36 | mean_na_rm <- partial(mean, na.rm = TRUE) 37 | mean_na_rm(airquality$Ozone) 38 | ``` 39 | 40 | ### Ok, but why? 41 | 42 | `partial(f, args = "x")` returns a function with a prefilled function with `args = "x"`. 43 | 44 | ### See also 45 | 46 | + [A Crazy Little Thing Called {purrr} - Part 5: code optimization](http://colinfay.me/purrr-code-optim/) 47 | 48 | 49 | --- 50 | 51 | ## Negate a function 52 | 53 | ### I want to... 54 | 55 | Inverse what a function does. 56 | 57 | ### Here's how to: 58 | 59 | ```{r} 60 | is_not_numeric <- negate(is.numeric) 61 | is_not_numeric("this") 62 | ``` 63 | 64 | ### Ok, but why? 65 | 66 | `negate(f)` returns a function that does `!f(...)`. 67 | 68 | ### See also 69 | 70 | --- 71 | 72 | ## Negate a function 73 | 74 | ### I want to... 75 | 76 | Change what input my function can take. 77 | 78 | ### Here's how to: 79 | 80 | ```{r} 81 | lifted_is_na <- lift_ld(is.na) 82 | lifted_is_na(1,2,3,NA) 83 | ``` 84 | 85 | ### Ok, but why? 86 | 87 | The `lift_*` family of functions change the type of input of other function. 88 | 89 | ### See also 90 | 91 | -------------------------------------------------------------------------------- /data-wrangling.Rmd: -------------------------------------------------------------------------------- 1 | # Data Wrangling {#wrangling} 2 | 3 | ## Read csvs 4 | 5 | ### I want to... 6 | 7 | Read a list of csv and turn them all into a data frame. 8 | 9 | ### Here's how to: 10 | 11 | ```{r message = FALSE} 12 | files <- list.files(pattern = "csv", full.names = TRUE) %>% 13 | set_names(basename(.)) 14 | full <- map_df(files, readr::read_csv, .id = "file") 15 | ``` 16 | 17 | ### Ok, but why? 18 | 19 | `map_df` maps the read_csv on all the files, and returns a data.frame. The `.id` is used to keep track of the original file. 20 | 21 | ### See also 22 | 23 | 24 | --- 25 | 26 | ## Remove the NA 27 | 28 | ### I want to... 29 | 30 | Remove the NA from my list. 31 | 32 | ### Here's how to: 33 | 34 | ```{r} 35 | l <- list(1, NA, "a", "b", NA) 36 | discard(l, is.na) 37 | ``` 38 | 39 | ### Ok, but why? 40 | 41 | `discard` is the opposite of `keep`, and removes all the elements that validate a condition. 42 | 43 | ### See also 44 | 45 | 46 | 47 | --- 48 | 49 | ## List append 50 | 51 | ### I want to... 52 | 53 | Add an element at the end of all my sublists. 54 | 55 | ### Here's how to: 56 | 57 | ```{r} 58 | l <- list(list(1:10, 1:20), list(20:30, 40:50)) 59 | modify_depth(l, 2, ~ prepend(.x, sum(.x))) 60 | ``` 61 | 62 | ### Ok, but why? 63 | 64 | `modify_depth` allows to map function in sublists at a given depth. 65 | 66 | `prepend` adds a element to the list at a givent index. If no index is given, the element is put at the beggining of the list. 67 | 68 | ### See also 69 | 70 | --- 71 | 72 | ## Position matching 73 | 74 | ### I want to... 75 | 76 | Find the first argument that matches a condition. 77 | 78 | ### Here's how to: 79 | 80 | ```{r} 81 | l <- 22:143 82 | detect_index(l, ~ sqrt(.x) == 9) 83 | ``` 84 | 85 | ### Ok, but why? 86 | 87 | `detect_index` returns the position of the first argument matching the condition. `detect` alone returns the value. 88 | 89 | You can pass the `.right` argument to these function, so that the search starts from the end of the list. 90 | 91 | ### See also 92 | 93 | --- 94 | 95 | ## Cut a list 96 | 97 | ### I want to... 98 | 99 | Takes all the arguments from a list until the condition is met. 100 | 101 | ### Here's how to: 102 | 103 | ```{r} 104 | l <- 22:143 105 | head_while(l, ~ sqrt(.x) < 9) 106 | ``` 107 | 108 | ### Ok, but why? 109 | 110 | `head_while`, and its counterpart `tail_while`, take a list and perform a `head` or `tail` until a predicate is validated. 111 | 112 | ### See also 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/css/plugin-bookdown.css: -------------------------------------------------------------------------------- 1 | .book .book-header h1 { 2 | padding-left: 20px; 3 | padding-right: 20px; 4 | } 5 | .book .book-header.fixed { 6 | position: fixed; 7 | right: 0; 8 | top: 0; 9 | left: 0; 10 | border-bottom: 1px solid rgba(0,0,0,.07); 11 | } 12 | span.search-highlight { 13 | background-color: #ffff88; 14 | } 15 | @media (min-width: 600px) { 16 | .book.with-summary .book-header.fixed { 17 | left: 300px; 18 | } 19 | } 20 | @media (max-width: 1240px) { 21 | .book .book-body.fixed { 22 | top: 50px; 23 | } 24 | .book .book-body.fixed .body-inner { 25 | top: auto; 26 | } 27 | } 28 | @media (max-width: 600px) { 29 | .book.with-summary .book-header.fixed { 30 | left: calc(100% - 60px); 31 | min-width: 300px; 32 | } 33 | .book.with-summary .book-body { 34 | transform: none; 35 | left: calc(100% - 60px); 36 | min-width: 300px; 37 | } 38 | .book .book-body.fixed { 39 | top: 0; 40 | } 41 | } 42 | 43 | .book .book-body.fixed .body-inner { 44 | top: 50px; 45 | } 46 | .book .book-body .page-wrapper .page-inner section.normal sub, .book .book-body .page-wrapper .page-inner section.normal sup { 47 | font-size: 85%; 48 | } 49 | 50 | @media print { 51 | .book .book-summary, .book .book-body .book-header, .fa { 52 | display: none !important; 53 | } 54 | .book .book-body.fixed { 55 | left: 0px; 56 | } 57 | .book .book-body,.book .book-body .body-inner, .book.with-summary { 58 | overflow: visible !important; 59 | } 60 | } 61 | .kable_wrapper { 62 | border-spacing: 20px 0; 63 | border-collapse: separate; 64 | border: none; 65 | margin: auto; 66 | } 67 | .kable_wrapper > tbody > tr > td { 68 | vertical-align: top; 69 | } 70 | .book .book-body .page-wrapper .page-inner section.normal table tr.header { 71 | border-top-width: 2px; 72 | } 73 | .book .book-body .page-wrapper .page-inner section.normal table tr:last-child td { 74 | border-bottom-width: 2px; 75 | } 76 | .book .book-body .page-wrapper .page-inner section.normal table td, .book .book-body .page-wrapper .page-inner section.normal table th { 77 | border-left: none; 78 | border-right: none; 79 | } 80 | .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr, .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr > td { 81 | border-top: none; 82 | } 83 | .book .book-body .page-wrapper .page-inner section.normal table.kable_wrapper > tbody > tr:last-child > td { 84 | border-bottom: none; 85 | } 86 | 87 | div.theorem, div.lemma, div.corollary, div.proposition { 88 | font-style: italic; 89 | } 90 | span.theorem, span.lemma, span.corollary, span.proposition { 91 | font-style: normal; 92 | } 93 | div.proof:after { 94 | content: "\25a2"; 95 | float: right; 96 | } 97 | .header-section-number { 98 | padding-right: .5em; 99 | } 100 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/css/plugin-fontsettings.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Theme 1 3 | */ 4 | .color-theme-1 .dropdown-menu { 5 | background-color: #111111; 6 | border-color: #7e888b; 7 | } 8 | .color-theme-1 .dropdown-menu .dropdown-caret .caret-inner { 9 | border-bottom: 9px solid #111111; 10 | } 11 | .color-theme-1 .dropdown-menu .buttons { 12 | border-color: #7e888b; 13 | } 14 | .color-theme-1 .dropdown-menu .button { 15 | color: #afa790; 16 | } 17 | .color-theme-1 .dropdown-menu .button:hover { 18 | color: #73553c; 19 | } 20 | /* 21 | * Theme 2 22 | */ 23 | .color-theme-2 .dropdown-menu { 24 | background-color: #2d3143; 25 | border-color: #272a3a; 26 | } 27 | .color-theme-2 .dropdown-menu .dropdown-caret .caret-inner { 28 | border-bottom: 9px solid #2d3143; 29 | } 30 | .color-theme-2 .dropdown-menu .buttons { 31 | border-color: #272a3a; 32 | } 33 | .color-theme-2 .dropdown-menu .button { 34 | color: #62677f; 35 | } 36 | .color-theme-2 .dropdown-menu .button:hover { 37 | color: #f4f4f5; 38 | } 39 | .book .book-header .font-settings .font-enlarge { 40 | line-height: 30px; 41 | font-size: 1.4em; 42 | } 43 | .book .book-header .font-settings .font-reduce { 44 | line-height: 30px; 45 | font-size: 1em; 46 | } 47 | .book.color-theme-1 .book-body { 48 | color: #704214; 49 | background: #f3eacb; 50 | } 51 | .book.color-theme-1 .book-body .page-wrapper .page-inner section { 52 | background: #f3eacb; 53 | } 54 | .book.color-theme-2 .book-body { 55 | color: #bdcadb; 56 | background: #1c1f2b; 57 | } 58 | .book.color-theme-2 .book-body .page-wrapper .page-inner section { 59 | background: #1c1f2b; 60 | } 61 | .book.font-size-0 .book-body .page-inner section { 62 | font-size: 1.2rem; 63 | } 64 | .book.font-size-1 .book-body .page-inner section { 65 | font-size: 1.4rem; 66 | } 67 | .book.font-size-2 .book-body .page-inner section { 68 | font-size: 1.6rem; 69 | } 70 | .book.font-size-3 .book-body .page-inner section { 71 | font-size: 2.2rem; 72 | } 73 | .book.font-size-4 .book-body .page-inner section { 74 | font-size: 4rem; 75 | } 76 | .book.font-family-0 { 77 | font-family: Georgia, serif; 78 | } 79 | .book.font-family-1 { 80 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 81 | } 82 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal { 83 | color: #704214; 84 | } 85 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a { 86 | color: inherit; 87 | } 88 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 89 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2, 90 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3, 91 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4, 92 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5, 93 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 94 | color: inherit; 95 | } 96 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 97 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 { 98 | border-color: inherit; 99 | } 100 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 101 | color: inherit; 102 | } 103 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr { 104 | background-color: inherit; 105 | } 106 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote { 107 | border-color: inherit; 108 | } 109 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, 110 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { 111 | background: #fdf6e3; 112 | color: #657b83; 113 | border-color: #f8df9c; 114 | } 115 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight { 116 | background-color: inherit; 117 | } 118 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th, 119 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td { 120 | border-color: #f5d06c; 121 | } 122 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr { 123 | color: inherit; 124 | background-color: #fdf6e3; 125 | border-color: #444444; 126 | } 127 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 128 | background-color: #fbeecb; 129 | } 130 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal { 131 | color: #bdcadb; 132 | } 133 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a { 134 | color: #3eb1d0; 135 | } 136 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 137 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2, 138 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3, 139 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4, 140 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5, 141 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 142 | color: #fffffa; 143 | } 144 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 145 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 { 146 | border-color: #373b4e; 147 | } 148 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 149 | color: #373b4e; 150 | } 151 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr { 152 | background-color: #373b4e; 153 | } 154 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote { 155 | border-color: #373b4e; 156 | } 157 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, 158 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { 159 | color: #9dbed8; 160 | background: #2d3143; 161 | border-color: #2d3143; 162 | } 163 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight { 164 | background-color: #282a39; 165 | } 166 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th, 167 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td { 168 | border-color: #3b3f54; 169 | } 170 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr { 171 | color: #b6c2d2; 172 | background-color: #2d3143; 173 | border-color: #3b3f54; 174 | } 175 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 176 | background-color: #35394b; 177 | } 178 | .book.color-theme-1 .book-header { 179 | color: #afa790; 180 | background: transparent; 181 | } 182 | .book.color-theme-1 .book-header .btn { 183 | color: #afa790; 184 | } 185 | .book.color-theme-1 .book-header .btn:hover { 186 | color: #73553c; 187 | background: none; 188 | } 189 | .book.color-theme-1 .book-header h1 { 190 | color: #704214; 191 | } 192 | .book.color-theme-2 .book-header { 193 | color: #7e888b; 194 | background: transparent; 195 | } 196 | .book.color-theme-2 .book-header .btn { 197 | color: #3b3f54; 198 | } 199 | .book.color-theme-2 .book-header .btn:hover { 200 | color: #fffff5; 201 | background: none; 202 | } 203 | .book.color-theme-2 .book-header h1 { 204 | color: #bdcadb; 205 | } 206 | .book.color-theme-1 .book-body .navigation { 207 | color: #afa790; 208 | } 209 | .book.color-theme-1 .book-body .navigation:hover { 210 | color: #73553c; 211 | } 212 | .book.color-theme-2 .book-body .navigation { 213 | color: #383f52; 214 | } 215 | .book.color-theme-2 .book-body .navigation:hover { 216 | color: #fffff5; 217 | } 218 | /* 219 | * Theme 1 220 | */ 221 | .book.color-theme-1 .book-summary { 222 | color: #afa790; 223 | background: #111111; 224 | border-right: 1px solid rgba(0, 0, 0, 0.07); 225 | } 226 | .book.color-theme-1 .book-summary .book-search { 227 | background: transparent; 228 | } 229 | .book.color-theme-1 .book-summary .book-search input, 230 | .book.color-theme-1 .book-summary .book-search input:focus { 231 | border: 1px solid transparent; 232 | } 233 | .book.color-theme-1 .book-summary ul.summary li.divider { 234 | background: #7e888b; 235 | box-shadow: none; 236 | } 237 | .book.color-theme-1 .book-summary ul.summary li i.fa-check { 238 | color: #33cc33; 239 | } 240 | .book.color-theme-1 .book-summary ul.summary li.done > a { 241 | color: #877f6a; 242 | } 243 | .book.color-theme-1 .book-summary ul.summary li a, 244 | .book.color-theme-1 .book-summary ul.summary li span { 245 | color: #877f6a; 246 | background: transparent; 247 | font-weight: normal; 248 | } 249 | .book.color-theme-1 .book-summary ul.summary li.active > a, 250 | .book.color-theme-1 .book-summary ul.summary li a:hover { 251 | color: #704214; 252 | background: transparent; 253 | font-weight: normal; 254 | } 255 | /* 256 | * Theme 2 257 | */ 258 | .book.color-theme-2 .book-summary { 259 | color: #bcc1d2; 260 | background: #2d3143; 261 | border-right: none; 262 | } 263 | .book.color-theme-2 .book-summary .book-search { 264 | background: transparent; 265 | } 266 | .book.color-theme-2 .book-summary .book-search input, 267 | .book.color-theme-2 .book-summary .book-search input:focus { 268 | border: 1px solid transparent; 269 | } 270 | .book.color-theme-2 .book-summary ul.summary li.divider { 271 | background: #272a3a; 272 | box-shadow: none; 273 | } 274 | .book.color-theme-2 .book-summary ul.summary li i.fa-check { 275 | color: #33cc33; 276 | } 277 | .book.color-theme-2 .book-summary ul.summary li.done > a { 278 | color: #62687f; 279 | } 280 | .book.color-theme-2 .book-summary ul.summary li a, 281 | .book.color-theme-2 .book-summary ul.summary li span { 282 | color: #c1c6d7; 283 | background: transparent; 284 | font-weight: 600; 285 | } 286 | .book.color-theme-2 .book-summary ul.summary li.active > a, 287 | .book.color-theme-2 .book-summary ul.summary li a:hover { 288 | color: #f4f4f5; 289 | background: #252737; 290 | font-weight: 600; 291 | } 292 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/css/plugin-search.css: -------------------------------------------------------------------------------- 1 | .book .book-summary .book-search { 2 | padding: 6px; 3 | background: transparent; 4 | position: absolute; 5 | top: -50px; 6 | left: 0px; 7 | right: 0px; 8 | transition: top 0.5s ease; 9 | } 10 | .book .book-summary .book-search input, 11 | .book .book-summary .book-search input:focus, 12 | .book .book-summary .book-search input:hover { 13 | width: 100%; 14 | background: transparent; 15 | border: 1px solid #ccc; 16 | box-shadow: none; 17 | outline: none; 18 | line-height: 22px; 19 | padding: 7px 4px; 20 | color: inherit; 21 | box-sizing: border-box; 22 | } 23 | .book.with-search .book-summary .book-search { 24 | top: 0px; 25 | } 26 | .book.with-search .book-summary ul.summary { 27 | top: 50px; 28 | } 29 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/js/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["jQuery"], function(jQuery) { 2 | 3 | /* 4 | * jQuery Highlight plugin 5 | * 6 | * Based on highlight v3 by Johann Burkard 7 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 8 | * 9 | * Code a little bit refactored and cleaned (in my humble opinion). 10 | * Most important changes: 11 | * - has an option to highlight only entire words (wordsOnly - false by default), 12 | * - has an option to be case sensitive (caseSensitive - false by default) 13 | * - highlight element tag and class names can be specified in options 14 | * 15 | * Copyright (c) 2009 Bartek Szopka 16 | * 17 | * Licensed under MIT license. 18 | * 19 | */ 20 | 21 | jQuery.extend({ 22 | highlight: function (node, re, nodeName, className) { 23 | if (node.nodeType === 3) { 24 | var match = node.data.match(re); 25 | if (match) { 26 | var highlight = document.createElement(nodeName || 'span'); 27 | highlight.className = className || 'highlight'; 28 | var wordNode = node.splitText(match.index); 29 | wordNode.splitText(match[0].length); 30 | var wordClone = wordNode.cloneNode(true); 31 | highlight.appendChild(wordClone); 32 | wordNode.parentNode.replaceChild(highlight, wordNode); 33 | return 1; //skip added node in parent 34 | } 35 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 36 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 37 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 38 | for (var i = 0; i < node.childNodes.length; i++) { 39 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 40 | } 41 | } 42 | return 0; 43 | } 44 | }); 45 | 46 | jQuery.fn.unhighlight = function (options) { 47 | var settings = { className: 'highlight', element: 'span' }; 48 | jQuery.extend(settings, options); 49 | 50 | return this.find(settings.element + "." + settings.className).each(function () { 51 | var parent = this.parentNode; 52 | parent.replaceChild(this.firstChild, this); 53 | parent.normalize(); 54 | }).end(); 55 | }; 56 | 57 | jQuery.fn.highlight = function (words, options) { 58 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 59 | jQuery.extend(settings, options); 60 | 61 | if (words.constructor === String) { 62 | words = [words]; 63 | } 64 | words = jQuery.grep(words, function(word, i){ 65 | return word !== ''; 66 | }); 67 | words = jQuery.map(words, function(word, i) { 68 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 69 | }); 70 | if (words.length === 0) { return this; } 71 | 72 | var flag = settings.caseSensitive ? "" : "i"; 73 | var pattern = "(" + words.join("|") + ")"; 74 | if (settings.wordsOnly) { 75 | pattern = "\\b" + pattern + "\\b"; 76 | } 77 | var re = new RegExp(pattern, flag); 78 | 79 | return this.each(function () { 80 | jQuery.highlight(this, re, settings.element, settings.className); 81 | }); 82 | }; 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/js/lunr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 3 | * Copyright (C) 2015 Oliver Nightingale 4 | * MIT Licensed 5 | * @license 6 | */ 7 | !function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-\/]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n's that are truncated 95 | $('a').each(function(i, el) { 96 | if (el.offsetWidth >= el.scrollWidth) return; 97 | if (typeof el.title === 'undefined') return; 98 | el.title = el.text; 99 | }); 100 | 101 | // restore TOC scroll position 102 | var pos = gs.get('tocScrollTop'); 103 | if (typeof pos !== 'undefined') summary.scrollTop(pos); 104 | 105 | // highlight the TOC item that has same text as the heading in view as scrolling 106 | if (toc && toc.scroll_highlight !== false) (function() { 107 | // scroll the current TOC item into viewport 108 | var ht = $(window).height(), rect = li[0].getBoundingClientRect(); 109 | if (rect.top >= ht || rect.top <= 0 || rect.bottom <= 0) { 110 | summary.scrollTop(li[0].offsetTop); 111 | } 112 | // current chapter TOC items 113 | var items = $('a[href^="' + href + '"]').parent('li.chapter'), 114 | m = items.length; 115 | if (m === 0) { 116 | items = summary.find('li.chapter'); 117 | m = items.length; 118 | } 119 | if (m === 0) return; 120 | // all section titles on current page 121 | var hs = bookInner.find('.page-inner').find('h1,h2,h3'), n = hs.length, 122 | ts = hs.map(function(i, el) { return $(el).text(); }); 123 | if (n === 0) return; 124 | var scrollHandler = function(e) { 125 | var ht = $(window).height(); 126 | clearTimeout($.data(this, 'scrollTimer')); 127 | $.data(this, 'scrollTimer', setTimeout(function() { 128 | // find the first visible title in the viewport 129 | for (var i = 0; i < n; i++) { 130 | var rect = hs[i].getBoundingClientRect(); 131 | if (rect.top >= 0 && rect.bottom <= ht) break; 132 | } 133 | if (i === n) return; 134 | items.removeClass('active'); 135 | for (var j = 0; j < m; j++) { 136 | if (items.eq(j).children('a').first().text() === ts[i]) break; 137 | } 138 | if (j === m) j = 0; // highlight the chapter title 139 | // search bottom-up for a visible TOC item to highlight; if an item is 140 | // hidden, we check if its parent is visible, and so on 141 | while (j > 0 && items.eq(j).is(':hidden')) j--; 142 | items.eq(j).addClass('active'); 143 | }, 250)); 144 | }; 145 | bookInner.on('scroll.bookdown', scrollHandler); 146 | bookBody.on('scroll.bookdown', scrollHandler); 147 | })(); 148 | 149 | // do not refresh the page if the TOC item points to the current page 150 | $('a[href="' + href + '"]').parent('li.chapter').children('a') 151 | .on('click', function(e) { 152 | bookInner.scrollTop(0); 153 | bookBody.scrollTop(0); 154 | return false; 155 | }); 156 | 157 | var toolbar = config.toolbar; 158 | if (!toolbar || toolbar.position !== 'static') { 159 | var bookHeader = $('.book-header'); 160 | bookBody.addClass('fixed'); 161 | bookHeader.addClass('fixed') 162 | .css('background-color', bookBody.css('background-color')) 163 | .on('click.bookdown', function(e) { 164 | // the theme may have changed after user clicks the theme button 165 | bookHeader.css('background-color', bookBody.css('background-color')); 166 | }); 167 | } 168 | 169 | }); 170 | 171 | gitbook.events.bind("page.change", function(e) { 172 | // store TOC scroll position 173 | var summary = $('ul.summary'); 174 | gs.set('tocScrollTop', summary.scrollTop()); 175 | }); 176 | 177 | var bookBody = $('.book-body'), bookInner = bookBody.find('.body-inner'); 178 | var chapterTitle = function() { 179 | return bookInner.find('.page-inner').find('h1,h2').first().text(); 180 | }; 181 | var bookTitle = function() { 182 | return bookInner.find('.book-header > h1').first().text(); 183 | }; 184 | var saveScrollPos = function(e) { 185 | // save scroll position before page is reloaded 186 | gs.set('bodyScrollTop', { 187 | body: bookBody.scrollTop(), 188 | inner: bookInner.scrollTop(), 189 | focused: document.hasFocus(), 190 | title: chapterTitle() 191 | }); 192 | }; 193 | $(document).on('servr:reload', saveScrollPos); 194 | 195 | // check if the page is loaded in an iframe (e.g. the RStudio preview window) 196 | var inIFrame = function() { 197 | var inIframe = true; 198 | try { inIframe = window.self !== window.top; } catch (e) {} 199 | return inIframe; 200 | }; 201 | $(window).on('blur unload', function(e) { 202 | if (inIFrame()) saveScrollPos(e); 203 | gs.set('bookTitle', bookTitle()); 204 | }); 205 | 206 | $(function(e) { 207 | if (gs.get('bookTitle', '') !== bookTitle()) localStorage.clear(); 208 | var pos = gs.get('bodyScrollTop'); 209 | if (pos) { 210 | if (pos.title === chapterTitle()) { 211 | if (pos.body !== 0) bookBody.scrollTop(pos.body); 212 | if (pos.inner !== 0) bookInner.scrollTop(pos.inner); 213 | } 214 | if (pos.focused) bookInner.find('.page-wrapper').focus(); 215 | } 216 | // clear book body scroll position 217 | gs.remove('bodyScrollTop'); 218 | }); 219 | 220 | }); 221 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/js/plugin-fontsettings.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var fontState; 3 | 4 | var THEMES = { 5 | "white": 0, 6 | "sepia": 1, 7 | "night": 2 8 | }; 9 | 10 | var FAMILY = { 11 | "serif": 0, 12 | "sans": 1 13 | }; 14 | 15 | // Save current font settings 16 | function saveFontSettings() { 17 | gitbook.storage.set("fontState", fontState); 18 | update(); 19 | } 20 | 21 | // Increase font size 22 | function enlargeFontSize(e) { 23 | e.preventDefault(); 24 | if (fontState.size >= 4) return; 25 | 26 | fontState.size++; 27 | saveFontSettings(); 28 | }; 29 | 30 | // Decrease font size 31 | function reduceFontSize(e) { 32 | e.preventDefault(); 33 | if (fontState.size <= 0) return; 34 | 35 | fontState.size--; 36 | saveFontSettings(); 37 | }; 38 | 39 | // Change font family 40 | function changeFontFamily(index, e) { 41 | e.preventDefault(); 42 | 43 | fontState.family = index; 44 | saveFontSettings(); 45 | }; 46 | 47 | // Change type of color 48 | function changeColorTheme(index, e) { 49 | e.preventDefault(); 50 | 51 | var $book = $(".book"); 52 | 53 | if (fontState.theme !== 0) 54 | $book.removeClass("color-theme-"+fontState.theme); 55 | 56 | fontState.theme = index; 57 | if (fontState.theme !== 0) 58 | $book.addClass("color-theme-"+fontState.theme); 59 | 60 | saveFontSettings(); 61 | }; 62 | 63 | function update() { 64 | var $book = gitbook.state.$book; 65 | 66 | $(".font-settings .font-family-list li").removeClass("active"); 67 | $(".font-settings .font-family-list li:nth-child("+(fontState.family+1)+")").addClass("active"); 68 | 69 | $book[0].className = $book[0].className.replace(/\bfont-\S+/g, ''); 70 | $book.addClass("font-size-"+fontState.size); 71 | $book.addClass("font-family-"+fontState.family); 72 | 73 | if(fontState.theme !== 0) { 74 | $book[0].className = $book[0].className.replace(/\bcolor-theme-\S+/g, ''); 75 | $book.addClass("color-theme-"+fontState.theme); 76 | } 77 | }; 78 | 79 | function init(config) { 80 | var $bookBody, $book; 81 | 82 | //Find DOM elements. 83 | $book = gitbook.state.$book; 84 | $bookBody = $book.find(".book-body"); 85 | 86 | // Instantiate font state object 87 | fontState = gitbook.storage.get("fontState", { 88 | size: config.size || 2, 89 | family: FAMILY[config.family || "sans"], 90 | theme: THEMES[config.theme || "white"] 91 | }); 92 | 93 | update(); 94 | }; 95 | 96 | 97 | gitbook.events.bind("start", function(e, config) { 98 | var opts = config.fontsettings; 99 | 100 | // Create buttons in toolbar 101 | gitbook.toolbar.createButton({ 102 | icon: 'fa fa-font', 103 | label: 'Font Settings', 104 | className: 'font-settings', 105 | dropdown: [ 106 | [ 107 | { 108 | text: 'A', 109 | className: 'font-reduce', 110 | onClick: reduceFontSize 111 | }, 112 | { 113 | text: 'A', 114 | className: 'font-enlarge', 115 | onClick: enlargeFontSize 116 | } 117 | ], 118 | [ 119 | { 120 | text: 'Serif', 121 | onClick: _.partial(changeFontFamily, 0) 122 | }, 123 | { 124 | text: 'Sans', 125 | onClick: _.partial(changeFontFamily, 1) 126 | } 127 | ], 128 | [ 129 | { 130 | text: 'White', 131 | onClick: _.partial(changeColorTheme, 0) 132 | }, 133 | { 134 | text: 'Sepia', 135 | onClick: _.partial(changeColorTheme, 1) 136 | }, 137 | { 138 | text: 'Night', 139 | onClick: _.partial(changeColorTheme, 2) 140 | } 141 | ] 142 | ] 143 | }); 144 | 145 | 146 | // Init current settings 147 | init(opts); 148 | }); 149 | }); 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/js/plugin-search.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var index = null; 3 | var $searchInput, $searchForm; 4 | var $highlighted, hi = 0, hiOpts = { className: 'search-highlight' }; 5 | var collapse = false; 6 | 7 | // Use a specific index 8 | function loadIndex(data) { 9 | // [Yihui] In bookdown, I use a character matrix to store the chapter 10 | // content, and the index is dynamically built on the client side. 11 | // Gitbook prebuilds the index data instead: https://github.com/GitbookIO/plugin-search 12 | // We can certainly do that via R packages V8 and jsonlite, but let's 13 | // see how slow it really is before improving it. On the other hand, 14 | // lunr cannot handle non-English text very well, e.g. the default 15 | // tokenizer cannot deal with Chinese text, so we may want to replace 16 | // lunr with a dumb simple text matching approach. 17 | index = lunr(function () { 18 | this.ref('url'); 19 | this.field('title', { boost: 10 }); 20 | this.field('body'); 21 | }); 22 | data.map(function(item) { 23 | index.add({ 24 | url: item[0], 25 | title: item[1], 26 | body: item[2] 27 | }); 28 | }); 29 | } 30 | 31 | // Fetch the search index 32 | function fetchIndex() { 33 | return $.getJSON(gitbook.state.basePath+"/search_index.json") 34 | .then(loadIndex); // [Yihui] we need to use this object later 35 | } 36 | 37 | // Search for a term and return results 38 | function search(q) { 39 | if (!index) return; 40 | 41 | var results = _.chain(index.search(q)) 42 | .map(function(result) { 43 | var parts = result.ref.split("#"); 44 | return { 45 | path: parts[0], 46 | hash: parts[1] 47 | }; 48 | }) 49 | .value(); 50 | 51 | // [Yihui] Highlight the search keyword on current page 52 | hi = 0; 53 | $highlighted = results.length === 0 ? undefined : $('.page-inner') 54 | .unhighlight(hiOpts).highlight(q, hiOpts).find('span.search-highlight'); 55 | scrollToHighlighted(); 56 | toggleTOC(results.length > 0); 57 | 58 | return results; 59 | } 60 | 61 | // [Yihui] Scroll the chapter body to the i-th highlighted string 62 | function scrollToHighlighted() { 63 | if (!$highlighted) return; 64 | var n = $highlighted.length; 65 | if (n === 0) return; 66 | var $p = $highlighted.eq(hi), p = $p[0], rect = p.getBoundingClientRect(); 67 | if (rect.top < 0 || rect.bottom > $(window).height()) { 68 | ($(window).width() >= 1240 ? $('.body-inner') : $('.book-body')) 69 | .scrollTop(p.offsetTop - 100); 70 | } 71 | $highlighted.css('background-color', ''); 72 | // an orange background color on the current item and removed later 73 | $p.css('background-color', 'orange'); 74 | setTimeout(function() { 75 | $p.css('background-color', ''); 76 | }, 2000); 77 | } 78 | 79 | // [Yihui] Expand/collapse TOC 80 | function toggleTOC(show) { 81 | if (!collapse) return; 82 | var toc_sub = $('ul.summary').children('li[data-level]').children('ul'); 83 | if (show) return toc_sub.show(); 84 | var href = window.location.pathname; 85 | href = href.substr(href.lastIndexOf('/') + 1); 86 | if (href === '') href = 'index.html'; 87 | var li = $('a[href^="' + href + location.hash + '"]').parent('li.chapter').first(); 88 | toc_sub.hide().parent().has(li).children('ul').show(); 89 | li.children('ul').show(); 90 | } 91 | 92 | // Create search form 93 | function createForm(value) { 94 | if ($searchForm) $searchForm.remove(); 95 | if ($searchInput) $searchInput.remove(); 96 | 97 | $searchForm = $('
    ', { 98 | 'class': 'book-search', 99 | 'role': 'search' 100 | }); 101 | 102 | $searchInput = $('', { 103 | 'type': 'search', 104 | 'class': 'form-control', 105 | 'val': value, 106 | 'placeholder': 'Type to search' 107 | }); 108 | 109 | $searchInput.appendTo($searchForm); 110 | $searchForm.prependTo(gitbook.state.$book.find('.book-summary')); 111 | } 112 | 113 | // Return true if search is open 114 | function isSearchOpen() { 115 | return gitbook.state.$book.hasClass("with-search"); 116 | } 117 | 118 | // Toggle the search 119 | function toggleSearch(_state) { 120 | if (isSearchOpen() === _state) return; 121 | if (!$searchInput) return; 122 | 123 | gitbook.state.$book.toggleClass("with-search", _state); 124 | 125 | // If search bar is open: focus input 126 | if (isSearchOpen()) { 127 | gitbook.sidebar.toggle(true); 128 | $searchInput.focus(); 129 | } else { 130 | $searchInput.blur(); 131 | $searchInput.val(""); 132 | gitbook.storage.remove("keyword"); 133 | gitbook.sidebar.filter(null); 134 | $('.page-inner').unhighlight(hiOpts); 135 | toggleTOC(false); 136 | } 137 | } 138 | 139 | // Recover current search when page changed 140 | function recoverSearch() { 141 | var keyword = gitbook.storage.get("keyword", ""); 142 | 143 | createForm(keyword); 144 | 145 | if (keyword.length > 0) { 146 | if(!isSearchOpen()) { 147 | toggleSearch(true); // [Yihui] open the search box 148 | } 149 | gitbook.sidebar.filter(_.pluck(search(keyword), "path")); 150 | } 151 | } 152 | 153 | 154 | gitbook.events.bind("start", function(e, config) { 155 | // [Yihui] disable search 156 | if (config.search === false) return; 157 | collapse = !config.toc || config.toc.collapse === 'section' || 158 | config.toc.collapse === 'subsection'; 159 | 160 | // Pre-fetch search index and create the form 161 | fetchIndex() 162 | // [Yihui] recover search after the page is loaded 163 | .then(recoverSearch); 164 | 165 | 166 | // Type in search bar 167 | $(document).on("keyup", ".book-search input", function(e) { 168 | var key = (e.keyCode ? e.keyCode : e.which); 169 | // [Yihui] Escape -> close search box; Up/Down: previous/next highlighted 170 | if (key == 27) { 171 | e.preventDefault(); 172 | toggleSearch(false); 173 | } else if (key == 38) { 174 | if (hi <= 0 && $highlighted) hi = $highlighted.length; 175 | hi--; 176 | scrollToHighlighted(); 177 | } else if (key == 40) { 178 | hi++; 179 | if ($highlighted && hi >= $highlighted.length) hi = 0; 180 | scrollToHighlighted(); 181 | } 182 | }).on("input", ".book-search input", function(e) { 183 | var q = $(this).val().trim(); 184 | if (q.length === 0) { 185 | gitbook.sidebar.filter(null); 186 | gitbook.storage.remove("keyword"); 187 | $('.page-inner').unhighlight(hiOpts); 188 | toggleTOC(false); 189 | } else { 190 | var results = search(q); 191 | gitbook.sidebar.filter( 192 | _.pluck(results, "path") 193 | ); 194 | gitbook.storage.set("keyword", q); 195 | } 196 | }); 197 | 198 | // Create the toggle search button 199 | gitbook.toolbar.createButton({ 200 | icon: 'fa fa-search', 201 | label: 'Search', 202 | position: 'left', 203 | onClick: toggleSearch 204 | }); 205 | 206 | // Bind keyboard to toggle search 207 | gitbook.keyboard.bind(['f'], toggleSearch); 208 | }); 209 | 210 | // [Yihui] do not try to recover search; always start fresh 211 | // gitbook.events.bind("page.change", recoverSearch); 212 | }); 213 | -------------------------------------------------------------------------------- /docs/libs/gitbook-2.6.7/js/plugin-sharing.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "lodash", "jQuery"], function(gitbook, _, $) { 2 | var SITES = { 3 | 'github': { 4 | 'label': 'Github', 5 | 'icon': 'fa fa-github', 6 | 'onClick': function(e) { 7 | e.preventDefault(); 8 | var repo = $('meta[name="github-repo"]').attr('content'); 9 | if (typeof repo === 'undefined') throw("Github repo not defined"); 10 | window.open("https://github.com/"+repo); 11 | } 12 | }, 13 | 'facebook': { 14 | 'label': 'Facebook', 15 | 'icon': 'fa fa-facebook', 16 | 'onClick': function(e) { 17 | e.preventDefault(); 18 | window.open("http://www.facebook.com/sharer/sharer.php?s=100&p[url]="+encodeURIComponent(location.href)); 19 | } 20 | }, 21 | 'twitter': { 22 | 'label': 'Twitter', 23 | 'icon': 'fa fa-twitter', 24 | 'onClick': function(e) { 25 | e.preventDefault(); 26 | window.open("http://twitter.com/home?status="+encodeURIComponent(document.title+" "+location.href)); 27 | } 28 | }, 29 | 'google': { 30 | 'label': 'Google+', 31 | 'icon': 'fa fa-google-plus', 32 | 'onClick': function(e) { 33 | e.preventDefault(); 34 | window.open("https://plus.google.com/share?url="+encodeURIComponent(location.href)); 35 | } 36 | }, 37 | 'weibo': { 38 | 'label': 'Weibo', 39 | 'icon': 'fa fa-weibo', 40 | 'onClick': function(e) { 41 | e.preventDefault(); 42 | window.open("http://service.weibo.com/share/share.php?content=utf-8&url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title)); 43 | } 44 | }, 45 | 'instapaper': { 46 | 'label': 'Instapaper', 47 | 'icon': 'fa fa-instapaper', 48 | 'onClick': function(e) { 49 | e.preventDefault(); 50 | window.open("http://www.instapaper.com/text?u="+encodeURIComponent(location.href)); 51 | } 52 | }, 53 | 'vk': { 54 | 'label': 'VK', 55 | 'icon': 'fa fa-vk', 56 | 'onClick': function(e) { 57 | e.preventDefault(); 58 | window.open("http://vkontakte.ru/share.php?url="+encodeURIComponent(location.href)); 59 | } 60 | } 61 | }; 62 | 63 | 64 | 65 | gitbook.events.bind("start", function(e, config) { 66 | var opts = config.sharing; 67 | if (!opts) return; 68 | 69 | // Create dropdown menu 70 | var menu = _.chain(opts.all) 71 | .map(function(id) { 72 | var site = SITES[id]; 73 | 74 | return { 75 | text: site.label, 76 | onClick: site.onClick 77 | }; 78 | }) 79 | .compact() 80 | .value(); 81 | 82 | // Create main button with dropdown 83 | if (menu.length > 0) { 84 | gitbook.toolbar.createButton({ 85 | icon: 'fa fa-share-alt', 86 | label: 'Share', 87 | position: 'right', 88 | dropdown: [menu] 89 | }); 90 | } 91 | 92 | // Direct actions to share 93 | _.each(SITES, function(site, sideId) { 94 | if (!opts[sideId]) return; 95 | 96 | gitbook.toolbar.createButton({ 97 | icon: site.icon, 98 | label: site.text, 99 | position: 'right', 100 | onClick: site.onClick 101 | }); 102 | }); 103 | }); 104 | }); 105 | -------------------------------------------------------------------------------- /docs/purrr_hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrr_hex.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-11-2.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-12-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-12-2.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/purrrcookbook_files/figure-html/unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/docs/purrrcookbook_files/figure-html/unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /docs/search_index.json: -------------------------------------------------------------------------------- 1 | [ 2 | ["how-to-read-this-book.html", "How to read this book Who is this cookbook for? Before reading You want another receipe You want to share a receipe What to do if you find a typo", " How to read this book This book is divided in 5 chapters. Each chapter contains a random number of receipes, more or less from the easiest to more complex examples. “Statistics” contains a list of useful common stat tricks with {purrr} “Webmining” gives you elements to mine info from the web (HTML / JSON) “Text Wrangling” covers some text mining methods “Code optimisation” is a chapter about using {purrr} to write better code “Data Wrangling” is a list of receipes I couldn’t fit anywhere else ¯\\(ツ)/¯ Based on other programming cookbook template, each receipe is divided as such: “I want to…”: what you want to do “Here’s how to”: how to do this “Ok, but why?”: more explanations about the solution “See also”: further references if you want to go deeper Who is this cookbook for? Anybody interested in learning more about {purrr}, either by reading this from cover to cover (well… figuratively speaking), of by picking what you find interesting. Before reading We expect the reader to be a little bit familiar with R, and with the core packages from the tidyverse. Copy and paste the below code to be sure you have all the packages you need. install.packages("tidyverse") install.packages("broom") install.packages("rvest") install.packages("attempt") install.packages("tidystringdist") install.packages("tidytext") Let’s launch the tidyverse to be sure we have everything we need: library(tidyverse) You want another receipe For another receipe, please ask on this issue. You want to share a receipe I’ll be glad to add other {purrr} receipes, so if ever you want to share one (or more), feel free to make a PR on the GitHub repo. What to do if you find a typo Nobody’s perfect and this book might contains typos. So please, yes please, open a PR (or feel free to reach me on Twitter) "] 3 | ] 4 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | p.caption { 2 | color: #777; 3 | margin-top: 10px; 4 | } 5 | p code { 6 | white-space: inherit; 7 | } 8 | pre { 9 | word-break: normal; 10 | word-wrap: normal; 11 | } 12 | pre code { 13 | white-space: inherit; 14 | } 15 | -------------------------------------------------------------------------------- /index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "purrr cookbook" 3 | author: "Colin Fay" 4 | date: "Last update on: `r Sys.Date()`" 5 | knit: "bookdown::render_book" 6 | site: bookdown::bookdown_site 7 | output: bookdown::gitbook 8 | documentclass: book 9 | bibliography: [book.bib, packages.bib] 10 | biblio-style: apalike 11 | link-citations: true 12 | links-as-notes: true 13 | colorlinks: true 14 | description: "A {purrr} cookbookdown." 15 | --- 16 | 17 | ```{r include=FALSE} 18 | # automatically create a bib database for R packages 19 | knitr::write_bib(c( 20 | .packages(), 'bookdown', 'knitr', 'rmarkdown', 'purrr' 21 | ), 'packages.bib') 22 | ``` 23 | 24 | # Welcome {-} 25 | 26 |
    27 | 28 | ```{r echo=FALSE, fig.align='center'} 29 | knitr::include_graphics("purrr_hex.png") 30 | ``` 31 | 32 |
    33 | 34 | This "cookbookdown" covers a series of common receipes you can do with {purrr}. 35 | 36 | It's based on several blogposts written on [colinfay.me](http://colinfay.me/tags/purrr/), some {purrr} code shared [on Twitter](https://twitter.com/i/moments/950031718521671680), and on some use-cases found or fought in the wild wild data world. 37 | 38 | As with any cookbook, this bookdwon is not intended at explaining in details what {purrr} does or how the functions used works. There is a short discussion after each receipes to quickly explain what the code does, but we won't go into specific details about each piece of code. For example, you won't find an explanation on the Shapiro Test in the chapter talking about this test. I also try to include (as much as possible) references to other articles / blogposts / books that can help you go deeper. 39 | 40 | And if ever you need more explanation, reach me on [Twitter](https://twitter.com/_ColinFay)! -------------------------------------------------------------------------------- /intro.Rmd: -------------------------------------------------------------------------------- 1 | # How to read this book {-} 2 | 3 | This book is divided in `r length(list.files(pattern = "Rmd")) - 4` chapters. 4 | 5 | Each chapter contains a random number of receipes, more or less from the easiest to more complex examples. 6 | 7 | - "Statistics" contains a list of useful common stat tricks with {purrr} 8 | - "Webmining" gives you elements to mine info from the web (HTML / JSON) 9 | - "Text Wrangling" covers some text mining methods 10 | - "Code optimisation" is a chapter about using {purrr} to write better code 11 | - "Data Wrangling" is a list of receipes I couldn't fit anywhere else ¯\\_(ツ)_/¯ 12 | 13 | Based on other programming cookbook template, each receipe is divided as such: 14 | 15 | - "I want to...": what you want to do 16 | - "Here's how to": how to do this 17 | - "Ok, but why?": more explanations about the solution 18 | - "See also": further references if you want to go deeper 19 | 20 | ## Who is this cookbook for? {-} 21 | 22 | Anybody interested in learning more about {purrr}, either by reading this from cover to cover (well... figuratively speaking), of by picking what you find interesting. 23 | 24 | ## Before reading {-} 25 | 26 | We expect the reader to be a little bit familiar with R, and with the core packages from the tidyverse. 27 | 28 | Copy and paste the below code to be sure you have all the packages you need. 29 | 30 | ```{r eval = FALSE} 31 | install.packages("tidyverse") 32 | install.packages("broom") 33 | install.packages("rvest") 34 | install.packages("attempt") 35 | install.packages("tidystringdist") 36 | install.packages("tidytext") 37 | ``` 38 | 39 | Let's launch the tidyverse to be sure we have everything we need: 40 | 41 | ```{r} 42 | library(tidyverse) 43 | ``` 44 | 45 | 46 | ## You want another receipe {-} 47 | 48 | For another receipe, please ask on [this issue](https://github.com/ColinFay/purrr-cookbook/issues/1). 49 | 50 | ## You want to share a receipe {-} 51 | 52 | I'll be glad to add other {purrr} receipes, so if ever you want to share one (or more), feel free to make a PR on the GitHub repo. 53 | 54 | ## What to do if you find a typo {-} 55 | 56 | Nobody's perfect and this book might contains typos. So please, yes please, open a [PR](https://github.com/ColinFay/purrr-cookbook/pulls) (or feel free to reach me on [Twitter](https://twitter.com/_ColinFay)) 57 | -------------------------------------------------------------------------------- /packages.bib: -------------------------------------------------------------------------------- 1 | @Manual{R-attempt, 2 | title = {attempt: Easy Condition Handling}, 3 | author = {Colin Fay}, 4 | year = {2018}, 5 | note = {R package version 0.1.0}, 6 | url = {https://CRAN.R-project.org/package=attempt}, 7 | } 8 | @Manual{R-base, 9 | title = {R: A Language and Environment for Statistical Computing}, 10 | author = {{R Core Team}}, 11 | organization = {R Foundation for Statistical Computing}, 12 | address = {Vienna, Austria}, 13 | year = {2017}, 14 | url = {https://www.R-project.org/}, 15 | } 16 | @Manual{R-bookdown, 17 | title = {bookdown: Authoring Books and Technical Documents with R Markdown}, 18 | author = {Yihui Xie}, 19 | year = {2017}, 20 | note = {R package version 0.5.15}, 21 | url = {https://github.com/rstudio/bookdown}, 22 | } 23 | @Manual{R-broom, 24 | title = {broom: Convert Statistical Analysis Objects into Tidy Data Frames}, 25 | author = {David Robinson}, 26 | year = {2017}, 27 | note = {R package version 0.4.3}, 28 | url = {https://CRAN.R-project.org/package=broom}, 29 | } 30 | @Manual{R-caret, 31 | title = {caret: Classification and Regression Training}, 32 | author = {Max Kuhn. Contributions from Jed Wing and Steve Weston and Andre Williams and Chris Keefer and Allan Engelhardt and Tony Cooper and Zachary Mayer and Brenton Kenkel and the R Core Team and Michael Benesty and Reynald Lescarbeau and Andrew Ziem and Luca Scrucca and Yuan Tang and Can Candan and Tyler Hunt.}, 33 | year = {2017}, 34 | note = {R package version 6.0-77}, 35 | url = {https://CRAN.R-project.org/package=caret}, 36 | } 37 | @Manual{R-curl, 38 | title = {curl: A Modern and Flexible Web Client for R}, 39 | author = {Jeroen Ooms}, 40 | year = {2017}, 41 | note = {R package version 3.1}, 42 | url = {https://CRAN.R-project.org/package=curl}, 43 | } 44 | @Manual{R-dplyr, 45 | title = {dplyr: A Grammar of Data Manipulation}, 46 | author = {Hadley Wickham and Romain Francois and Lionel Henry and Kirill Müller}, 47 | year = {2017}, 48 | note = {R package version 0.7.4}, 49 | url = {https://CRAN.R-project.org/package=dplyr}, 50 | } 51 | @Manual{R-forcats, 52 | title = {forcats: Tools for Working with Categorical Variables (Factors)}, 53 | author = {Hadley Wickham}, 54 | year = {2017}, 55 | note = {R package version 0.2.0}, 56 | url = {https://CRAN.R-project.org/package=forcats}, 57 | } 58 | @Manual{R-ggplot2, 59 | title = {ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics}, 60 | author = {Hadley Wickham and Winston Chang}, 61 | year = {2016}, 62 | note = {R package version 2.2.1}, 63 | url = {https://CRAN.R-project.org/package=ggplot2}, 64 | } 65 | @Manual{R-httr, 66 | title = {httr: Tools for Working with URLs and HTTP}, 67 | author = {Hadley Wickham}, 68 | year = {2017}, 69 | note = {R package version 1.3.1}, 70 | url = {https://CRAN.R-project.org/package=httr}, 71 | } 72 | @Manual{R-knitr, 73 | title = {knitr: A General-Purpose Package for Dynamic Report Generation in R}, 74 | author = {Yihui Xie}, 75 | year = {2017}, 76 | note = {R package version 1.18}, 77 | url = {https://CRAN.R-project.org/package=knitr}, 78 | } 79 | @Manual{R-lattice, 80 | title = {lattice: Trellis Graphics for R}, 81 | author = {Deepayan Sarkar}, 82 | year = {2017}, 83 | note = {R package version 0.20-35}, 84 | url = {https://CRAN.R-project.org/package=lattice}, 85 | } 86 | @Manual{R-purrr, 87 | title = {purrr: Functional Programming Tools}, 88 | author = {Lionel Henry and Hadley Wickham}, 89 | note = {http://purrr.tidyverse.org, https://github.com/tidyverse/purrr}, 90 | year = {2017}, 91 | } 92 | @Manual{R-readr, 93 | title = {readr: Read Rectangular Text Data}, 94 | author = {Hadley Wickham and Jim Hester and Romain Francois}, 95 | year = {2017}, 96 | note = {R package version 1.1.1}, 97 | url = {https://CRAN.R-project.org/package=readr}, 98 | } 99 | @Manual{R-rmarkdown, 100 | title = {rmarkdown: Dynamic Documents for R}, 101 | author = {JJ Allaire and Yihui Xie and Jonathan McPherson and Javier Luraschi and Kevin Ushey and Aron Atkins and Hadley Wickham and Joe Cheng and Winston Chang}, 102 | note = {http://rmarkdown.rstudio.com, https://github.com/rstudio/rmarkdown}, 103 | year = {2017}, 104 | } 105 | @Manual{R-rpart, 106 | title = {rpart: Recursive Partitioning and Regression Trees}, 107 | author = {Terry Therneau and Beth Atkinson and Brian Ripley}, 108 | year = {2017}, 109 | note = {R package version 4.1-11}, 110 | url = {https://CRAN.R-project.org/package=rpart}, 111 | } 112 | @Manual{R-rvest, 113 | title = {rvest: Easily Harvest (Scrape) Web Pages}, 114 | author = {Hadley Wickham}, 115 | year = {2016}, 116 | note = {R package version 0.3.2}, 117 | url = {https://CRAN.R-project.org/package=rvest}, 118 | } 119 | @Manual{R-stringr, 120 | title = {stringr: Simple, Consistent Wrappers for Common String Operations}, 121 | author = {Hadley Wickham}, 122 | year = {2017}, 123 | note = {R package version 1.2.0}, 124 | url = {https://CRAN.R-project.org/package=stringr}, 125 | } 126 | @Manual{R-tibble, 127 | title = {tibble: Simple Data Frames}, 128 | author = {Kirill Müller and Hadley Wickham}, 129 | year = {2017}, 130 | note = {R package version 1.3.4}, 131 | url = {https://CRAN.R-project.org/package=tibble}, 132 | } 133 | @Manual{R-tidyr, 134 | title = {tidyr: Easily Tidy Data with 'spread()' and 'gather()' Functions}, 135 | author = {Hadley Wickham and Lionel Henry}, 136 | year = {2017}, 137 | note = {R package version 0.7.2}, 138 | url = {https://CRAN.R-project.org/package=tidyr}, 139 | } 140 | @Manual{R-tidystringdist, 141 | title = {tidystringdist: String Distance Calculation with Tidy Data Principles}, 142 | author = {Colin Fay}, 143 | note = {R package version 0.1.2}, 144 | year = {2017}, 145 | } 146 | @Manual{R-tidyverse, 147 | title = {tidyverse: Easily Install and Load the 'Tidyverse'}, 148 | author = {Hadley Wickham}, 149 | year = {2017}, 150 | note = {R package version 1.2.1}, 151 | url = {https://CRAN.R-project.org/package=tidyverse}, 152 | } 153 | @Manual{R-xml2, 154 | title = {xml2: Parse XML}, 155 | author = {Hadley Wickham and James Hester and Jeroen Ooms}, 156 | year = {2017}, 157 | note = {R package version 1.1.1}, 158 | url = {https://CRAN.R-project.org/package=xml2}, 159 | } 160 | -------------------------------------------------------------------------------- /preamble.tex: -------------------------------------------------------------------------------- 1 | \usepackage{booktabs} 2 | -------------------------------------------------------------------------------- /purrr_hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColinFay/purrr-cookbook/ef3637646fad43873f6f38136b253c8e38cbcd41/purrr_hex.png -------------------------------------------------------------------------------- /purrrcookbook.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Website 16 | -------------------------------------------------------------------------------- /skeleton: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## 4 | 5 | ### I want to... 6 | 7 | 8 | ### Here's how to: 9 | 10 | ```{r} 11 | 12 | ``` 13 | 14 | ### Ok, but why? 15 | 16 | 17 | 18 | ### See also 19 | 20 | -------------------------------------------------------------------------------- /statistics.Rmd: -------------------------------------------------------------------------------- 1 | # Statistics {#stats} 2 | 3 | ```{r} 4 | set.seed(2811) 5 | ``` 6 | 7 | ## Compute the mean 8 | 9 | ### I want to... 10 | 11 | Get the mean of vectors of unequal length. 12 | 13 | ### Here's how to: 14 | 15 | ```{r} 16 | numbers <- list(rnorm(10), rnorm(10), rnorm(1000)) 17 | trim <- 20 18 | na_rm <- TRUE 19 | pmap_dbl(list(numbers, trim, na_rm), ~ mean(..1, ..2,..3)) 20 | ``` 21 | 22 | ### Ok, but why? 23 | 24 | `pmap` takes a list of list as an input, and send them to the function. In `.f`, you can refer to the list arguments with their position: here, `..1`, `..2` and `..3`. 25 | 26 | ### See also 27 | 28 | --- 29 | 30 | ## Running a shapiro test 31 | 32 | Given the dataset `airquality`. 33 | 34 | ### I want to... 35 | 36 | Look for normality on all columns, and know the one which are normal: 37 | 38 | ### Here's how to: 39 | 40 | ```{r} 41 | map(airquality, shapiro.test) %>% keep(~ .x$p.value > 0.05) 42 | ``` 43 | 44 | ### Ok, but why? 45 | 46 | In R, data.frame are __lists of vectors of same length__. So, you can apply a function the same way you would apply a function on any list. Here, we are mapping a `shapiro.test`, on all columns, and we `keep` only the elements with a `.x$p.value` which is more than 0.05. 47 | 48 | ### See also 49 | 50 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 51 | 52 | --- 53 | 54 | ## Test only numeric columns 55 | 56 | ### I want to... 57 | 58 | Make sure I make my statistical test on numeric values. 59 | 60 | ### Here's how to: 61 | 62 | ```{r} 63 | map_if(.x = iris, .p = is.numeric, .f = shapiro.test) 64 | ``` 65 | 66 | ### Ok, but why? 67 | 68 | `map_if` runs `.f` only if the `.x` verifies the condition `.p`. 69 | 70 | ### See also 71 | 72 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 73 | 74 | --- 75 | 76 | ## cor.test 77 | 78 | ### I want to... 79 | 80 | Make a bulk cor.test of all my variables. 81 | 82 | ### Here's how to: 83 | 84 | ```{r} 85 | library(tidystringdist) # Works since v0.1.2 86 | comb <- tidy_comb_all(names(airquality)) 87 | pmap(comb, ~ cor.test(airquality[[.x]], airquality[[.y]])) %>% 88 | map_df(broom::tidy) %>% 89 | cbind(comb, .) %>% 90 | select(V1:parameter) 91 | ``` 92 | 93 | ### Ok, but why? 94 | 95 | `comb` is a table containing all combinations of the names of the columns. What we do is mapping a `cor.test` on all these combinations by extracting, each time, the column as a vector, with `airquality[[.x]]` and `airquality[[.y]]`. 96 | 97 | `pmap` allows to use a list as a signe input. 98 | 99 | ### See also 100 | 101 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 102 | 103 | --- 104 | 105 | ## Linear regression 106 | 107 | ### I want to... 108 | 109 | Get the r.squared of each of the possible lm of airquality combinations. 110 | 111 | ### Here's how to: 112 | 113 | ```{r} 114 | res <- pmap(comb, ~ lm(airquality[[.x]] ~ airquality[[.y]])) 115 | get_rsquared <- compose(as_mapper(~ .x$r.squared), summary) 116 | map_dbl(res, get_rsquared) 117 | ``` 118 | 119 | ### Ok, but why? 120 | 121 | We're building a model of all combinations with `pmap`, just as before with `cor.test`. 122 | 123 | Then, the `get_rsquared` function is a composition of extracting the r.squared of the summary of a lm result. `compose(x, y)` allows to build `x(y())`. Here, we are combining a mapper extracting the `r.squared` element out of the `summary()` of a `lm`. 124 | 125 | ### See also 126 | 127 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 128 | 129 | --- 130 | 131 | ## significant r.squared 132 | 133 | ### I want to... 134 | 135 | Know if some r.square are above O.5 : 136 | 137 | ### Here's how to: 138 | 139 | ```{r} 140 | res <- pmap(comb, ~ lm(airquality[[.x]] ~ airquality[[.y]])) 141 | get_rsquared <- compose(as_mapper(~ .x$r.squared), summary) 142 | map_dbl(res, get_rsquared) %>% some(~ .x > 0.5) 143 | ``` 144 | 145 | ### Ok, but why? 146 | 147 | `some` checks if any of the input validate the condition. 148 | 149 | ### See also 150 | 151 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 152 | 153 | --- 154 | 155 | ## test and validation 156 | 157 | ### I want to... 158 | 159 | Create 20 test and validation datasets. 160 | 161 | ### Here's how to: 162 | 163 | ```{r message=FALSE} 164 | # From http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic3.csv 165 | titanic <- readr::read_csv("titanic.csv") 166 | train <- rerun(20, sample_frac(titanic, size = 0.8)) 167 | validation <- map(train, ~ anti_join(titanic, .x)) 168 | ``` 169 | 170 | ### Ok, but why? 171 | 172 | `rerun` runs the sampling 20 times. To obtain the 20 validation sets, we anti-join each elements of the train list with the original dataframe. That way, `train[1]` + `validation[1]` = `titanic`, `train[2]` + `validation[2]` = `titanic`, etc 173 | 174 | ### See also 175 | 176 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 177 | 178 | --- 179 | 180 | ## rpart 181 | 182 | ### I want to... 183 | 184 | Create 20 `rpart`, modeled on my 20 elements in the `test` list. 185 | 186 | ### Here's how to: 187 | 188 | ```{r} 189 | library(rpart) 190 | rpart_pimped <- partial(rpart, formula = survived ~ sex, method = "class") 191 | res <- map(train, rpart_pimped) 192 | res[[1]] 193 | ``` 194 | 195 | ### Ok, but why? 196 | 197 | `partial` allows to build a prefil function, which is then mapped on each element. 198 | 199 | ### See also 200 | 201 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 202 | 203 | --- 204 | 205 | ## Make prediction 206 | 207 | ### I want to... 208 | 209 | Make prediction based on my models 210 | 211 | ### Here's how to: 212 | 213 | ```{r} 214 | prediction <- map2(validation, res, ~ predict(.y, .x, type = "class")) 215 | w_prediction <- map2(validation, prediction, ~ mutate(.x, prediction = .y)) 216 | ``` 217 | 218 | ### Ok, but why? 219 | 220 | `map2` allows to map on two arguments. 221 | 222 | ### See also 223 | 224 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 225 | 226 | --- 227 | 228 | ## Confusion matrix 229 | 230 | ### I want to... 231 | 232 | Create a conf matrix on all these results: 233 | 234 | ### Here's how to: 235 | 236 | ```{r} 237 | library(caret) 238 | conf_mats <- map(w_prediction, ~ confusionMatrix(.x$prediction, .x$survived)) 239 | ``` 240 | 241 | ### Ok, but why? 242 | 243 | You can use `.x` as many times as you want in `.f`. 244 | 245 | ### See also 246 | 247 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 248 | 249 | --- 250 | 251 | ## Sensitivity and Specificity 252 | 253 | ### I want to... 254 | 255 | Detect which models have a specificity above 0.7 and sensitivity above 0.85 (randomly chosen numbers). 256 | 257 | ### Here's how to: 258 | 259 | ```{r} 260 | keep_index <- function(.x, .p, ...) { 261 | sel <- purrr:::probe(.x, .p, ...) 262 | which(sel) 263 | } 264 | sens <- map_dbl(conf_mats, ~ .x$byClass["Sensitivity"]) %>% keep_index(~ .x > 0.85) 265 | spec <- map_dbl(conf_mats, ~ .x$byClass["Specificity"]) %>% keep_index(~ .x > 0.7) 266 | keep(sens, map_lgl(sens, ~ .x %in% spec)) 267 | ``` 268 | 269 | ### Ok, but why? 270 | 271 | We have created a function that returns the position of elements that validates a condition. `sens` is the vector containing the position with sensitivity above 0.85, `spec` the vector for specificity above 0.7. 272 | 273 | Then, we pass to `keep` a vector of logical built with `map_lgl`. This vector tells if each elements of `sens` is or isn't in `spec`. 274 | 275 | ### See also 276 | 277 | + [A Crazy Little Thing Called {purrr} - Part 6 : doing statistics](http://colinfay.me/purrr-statistics/) 278 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | p.caption { 2 | color: #777; 3 | margin-top: 10px; 4 | } 5 | p code { 6 | white-space: inherit; 7 | } 8 | pre { 9 | word-break: normal; 10 | word-wrap: normal; 11 | } 12 | pre code { 13 | white-space: inherit; 14 | } 15 | -------------------------------------------------------------------------------- /test.json: -------------------------------------------------------------------------------- 1 | { 2 | "obs1": { 3 | "id": "AA", 4 | "Age": "29", 5 | "Res": { 6 | "test1": "17", 7 | "test2": "12" 8 | } 9 | }, 10 | "obs2": { 11 | "id": "BB", 12 | "Age": "35", 13 | "Res": { 14 | "test1": "12", 15 | "test2": "5" 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /text-wrangling.Rmd: -------------------------------------------------------------------------------- 1 | # Text Mining {#tm} 2 | 3 | ## Build regex 4 | 5 | ### I want to... 6 | 7 | Automatically build a regex with or `|` 8 | 9 | ### Here's how to: 10 | 11 | ```{r} 12 | regex_build <- function(...){ 13 | reduce(list(...), ~ paste(.x, .y, sep = "|")) 14 | } 15 | regex_build("one","two","three", "four") 16 | ``` 17 | 18 | ### Ok, but why? 19 | 20 | `reduce` turns a list into one value by recursively applying a binary function to the list. In other words, `reduce(list("one","two","three"), ~ paste(.x, .y, sep = "|"))` does `paste("one", paste("two", paste("three", "four", sep = "|"), sep = "|"), sep = "|")`. 21 | 22 | ### See also 23 | 24 | --- 25 | 26 | ## Regex extraction 27 | 28 | ### I want to... 29 | 30 | Extract the elements from a list of words that match a regex 31 | 32 | ### Here's how to: 33 | 34 | ```{r} 35 | # Random words from https://www.randomlists.com/random-words 36 | words <- c("copper", "explain", "ill-fated", "truck", "neat","unite","branch","educated","tenuous", "hum","decisive","notice") 37 | # Extract words that end with a "e" 38 | my_regex <- "e$" 39 | keep(words, ~ grepl(my_regex, .x)) 40 | ``` 41 | 42 | ### Ok, but why? 43 | 44 | `keep` only keeps the element matching the predicate. Here, we're using `grepl`, that returns TRUE or FALSE if the expression is found in the string. 45 | 46 | ### See also 47 | 48 | --- 49 | 50 | ## Collapse a list of words 51 | 52 | Given the following list of hashtags: 53 | 54 | ```{r} 55 | hash <- list(tweet1 = c("#RStats", "#Datascience"), tweet2 = c("#RStats", "#BigData")) 56 | ``` 57 | 58 | ### I want to... 59 | 60 | Turn my list of words into a simple vector. 61 | 62 | ### Here's how to: 63 | 64 | ```{r} 65 | simplify(hash) %>% paste(collapse = " ") 66 | ``` 67 | 68 | ### Ok, but why? 69 | 70 | Simplify turns a list of n\*m elements into a vector of lenght n\*m. We then paste all the elements together, using the `collapse` argument from `paste`. 71 | 72 | ### See also 73 | 74 | 75 | -------------------------------------------------------------------------------- /webmining.Rmd: -------------------------------------------------------------------------------- 1 | # Webmining {#webmining} 2 | 3 | ## Status code 4 | 5 | ### I want to... 6 | 7 | Create a status code checker. 8 | 9 | ### Here's how to 10 | 11 | ```{r} 12 | library(httr) 13 | get_status <- compose(status_code, GET) 14 | get_status("colinfay.me") 15 | ``` 16 | 17 | ### Ok, but why? 18 | 19 | `compose(y, x)` composes a function that will do `y(x())`. So here, `get_status("url")` will do `status_code(GET("url"))`. 20 | 21 | ### See also 22 | 23 | --- 24 | 25 | ## Check status code 26 | 27 | ### I want to... 28 | 29 | Check for http status code for a list of pages. 30 | 31 | ### Here's how to 32 | 33 | ```{r} 34 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 35 | get_status <- compose(status_code, GET) 36 | map(urls, get_status) %>% every(~ .x == 200) 37 | ``` 38 | 39 | ### Ok, but why? 40 | 41 | 200 is a status code that indicates that the connexion went smoothly. The `every` function here checks if all the status code we just `GET` are equal to 200. 42 | 43 | ### See also 44 | 45 | --- 46 | ## Clean a list of urls 47 | 48 | ### I want to... 49 | 50 | Keep only the 200 codes from my list of `urls`. 51 | 52 | ### Here's how to 53 | 54 | ```{r} 55 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 56 | get_status <- compose(status_code, GET) 57 | map(urls, get_status) %>% set_names(nm = urls) %>% keep(~ .x == 200) 58 | ``` 59 | 60 | ### Ok, but why? 61 | 62 | `set_names` sets the name for all the elements from the list. You can either leave the function with just the list as first arg, or pass it another list of the same length as `x`. 63 | 64 | `keep` only keeps the elements that validate the condition. 65 | 66 | ### See also 67 | 68 | --- 69 | ## Scrape a list of urls which may fail 70 | 71 | ### I want to... 72 | 73 | Launch a `read_html` function on a list of webpages, and some may throw an error. 74 | 75 | The difference with the function we saw previously ? 76 | 77 | ```{r error = TRUE} 78 | # http status code error 79 | GET("notexistingurl") 80 | # Error because host doesn't exist 81 | GET("notexistingurl.org") 82 | ``` 83 | 84 | 85 | ### Here's how to 86 | 87 | ```{r} 88 | library(rvest) 89 | urls <- c("http://colinfay.me", "http://thinkr.fr", "reallynotanadress") 90 | possible_read <- possibly(read_html, otherwise = NULL) 91 | map(urls, possible_read) %>% set_names(urls) %>% compact() 92 | ``` 93 | 94 | ### Ok, but why 95 | 96 | `possibly` turns a function into another function that returns what is defined in otherwise in case of failure. Here, we chose to return NULL. 97 | 98 | `compact()` removes all the elements from a list which are NULL. 99 | 100 | ### See also 101 | 102 | + [R for Data Science - 21.6 Dealing with failure](http://r4ds.had.co.nz/iteration.html#dealing-with-failure) 103 | 104 | --- 105 | 106 | ## Getting h2 107 | 108 | ### I want to... 109 | 110 | Get the h2s from a list of urls. 111 | 112 | ### Here's how to 113 | 114 | ```{r} 115 | get_h2 <- compose(html_text, 116 | as_mapper(~ html_nodes(.x, "h2")), 117 | read_html) 118 | urls <- c("http://colinfay.me", "http://thinkr.fr") 119 | map(urls, get_h2) %>% set_names(urls) 120 | ``` 121 | 122 | ### Ok, but why? 123 | 124 | We are composing an h2 extractor by combining `read_html`, `html_nodes` and `html_text`. We then map this extractor to a list of urls, before setting the names of the results with the `set_names` function. 125 | 126 | ### See also 127 | 128 | --- 129 | ## Scrape JSON 130 | 131 | Given the following JSON files: 132 | 133 | ``` 134 | { 135 | "obs1": { 136 | "id": "AA", 137 | "Age": "29", 138 | "Res": { 139 | "test1": "17", 140 | "test2": "12" 141 | } 142 | }, 143 | "obs2": { 144 | "id": "BB", 145 | "Age": "35", 146 | "Res": { 147 | "test1": "12", 148 | "test2": "5" 149 | } 150 | } 151 | } 152 | ``` 153 | ```{r} 154 | json_file <- jsonlite::read_json("test.json") 155 | ``` 156 | 157 | ### I want to... 158 | 159 | Extract all the elements in "value". 160 | 161 | ### Here's how to: 162 | 163 | ```{r} 164 | map(json_file, "id") 165 | ``` 166 | 167 | ### Ok, but why? 168 | 169 | If you put a character vector as `.f`, `map` looks for all the elements with the name matching this vector. This call works for the first level of the list 170 | 171 | ### See also 172 | 173 | --- 174 | 175 | ## JSON with many levels 176 | 177 | ### I want to... 178 | 179 | Extract all the test1 results. 180 | 181 | ### Here's how to: 182 | 183 | ```{r} 184 | map(json_file, ~ purrr::pluck(.x, "Res", "test1")) 185 | ``` 186 | 187 | ### Ok, but why 188 | 189 | What we called before is a shortcut for `map(file, ~ pluck(.x, "id")`. That shortcut works on the first level of the list. If you need to go deeper, you need to explicitely specify the `pluck` call. 190 | 191 | Be careful, there is also a `pluck` in {rvest} that doesn't behave exactly as the `pluck` from {purrr}. 192 | 193 | ```{r error=TRUE} 194 | map(json_file, ~ rvest::pluck(.x, "Res", "test1")) 195 | ``` 196 | 197 | 198 | ### See also 199 | 200 | --- 201 | 202 | ## Several API call 203 | 204 | ### I want to... 205 | 206 | Make a series of API calls 207 | 208 | ### Here's how to: 209 | 210 | ```{r warning=FALSE} 211 | library(attempt) 212 | library(curl) 213 | caller <- function(x){ 214 | # verify internet connexion 215 | stop_if_not(has_internet(), msg = "You should have internet to do that") 216 | res <- GET(url = "https://geo.api.gouv.fr/communes", query = list(nom = x)) 217 | res$content %>% rawToChar() %>% jsonlite::fromJSON(simplifyDataFrame = TRUE) 218 | } 219 | city <- c("Rennes","Vannes","Brest") 220 | map_df(city, caller) 221 | ``` 222 | 223 | ### Ok, but why? 224 | 225 | Here, we are calling an API which returns a JSON object that can be easily turned into a df with {jsonlite}. So we choose to use `map_df` to return a simple data.frame of the three results. 226 | 227 | ### See also 228 | 229 | --------------------------------------------------------------------------------