Some googledrive functions are built to naturally handle multiple files, while others operate on a single file.
Functions that expect a single file:
drive_browse()drive_cp()drive_download()drive_ls()drive_mkdir()drive_mv()drive_rename()drive_update()drive_upload()Functions that allow multiple files:
In general, the principle is: if there are multiple parameters that are likely to vary across multiple files, the function is designed to take a single input. In order to use these function with multiple inputs, use them together with your favorite approach for iteration in R. Below is a worked example, focusing on tools in the tidyverse, namely the map() functions in purrr.
Scenario: we have multiple local files we want to upload into a folder on Drive. Then we regret their original names and want to rename them.
Load packages.
library(googledrive)
library(glue)
library(tidyverse)
#> ── Attaching packages ───────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 3.0.0 ✔ purrr 0.2.5
#> ✔ tibble 1.4.99.9004 ✔ dplyr 0.7.99.9000
#> ✔ tidyr 0.8.1 ✔ stringr 1.3.1
#> ✔ readr 1.2.0 ✔ forcats 0.3.0
#> ── Conflicts ──────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::collapse() masks glue::collapse()
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag() masks stats::lag()Use the example files that ship with googledrive. This looks a bit odd, but the first call returns their names and the second returns full paths on the local system.
Create a folder on your Drive and upload all files into this folder by iterating over the local_files using purrr::map().
folder <- drive_mkdir("upload-into-me-article-demo")
#> Folder created:
#> * upload-into-me-article-demo
files <- map(local_files, drive_upload, path = folder, verbose = FALSE)files is now a list of dribbles, one per uploaded file. Let’s confirm that we uploaded the file into the new folder.
str(files, max.level = 1)
#> List of 4
#> $ :Classes 'dribble', 'tbl_df', 'tbl' and 'data.frame': 1 obs. of 3 variables:
#> $ :Classes 'dribble', 'tbl_df', 'tbl' and 'data.frame': 1 obs. of 3 variables:
#> $ :Classes 'dribble', 'tbl_df', 'tbl' and 'data.frame': 1 obs. of 3 variables:
#> $ :Classes 'dribble', 'tbl_df', 'tbl' and 'data.frame': 1 obs. of 3 variables:
drive_ls(folder)
#> # A tibble: 4 x 3
#> name id drive_resource
#> * <chr> <chr> <list>
#> 1 chicken.txt 1fVtjsxBX62XLMrlRZGdZUbnsKxScbs6j <list [38]>
#> 2 chicken.pdf 1Tb6OYg7tknLclgjGD_7wiqX2_MB951j9 <list [39]>
#> 3 chicken.jpg 1PtMTFqV6Mj5HBuSqgZ8C8F3pHu_5SFTw <list [40]>
#> 4 chicken.csv 1OTsuUqQ_1PjJ1g1xg-IacIry7hdzCU88 <list [38]>Imagine that we now wish these file names had a date prefix. First, form the new names. We use glue::glue() for string interpolation but you could also use paste(). Second, we map over two inputs: the list of dribbles from above and the vector of new names.
new_names <- glue("{Sys.Date()}_{basename(local_files)}")
files_dribble <- map2_df(files, new_names, drive_rename)
#> File renamed:
#> * chicken.csv -> 2018-10-05_chicken.csv
#> File renamed:
#> * chicken.jpg -> 2018-10-05_chicken.jpg
#> File renamed:
#> * chicken.pdf -> 2018-10-05_chicken.pdf
#> File renamed:
#> * chicken.txt -> 2018-10-05_chicken.txt
## alternative: do this to get a list of dribbles for more downstream mapping
# files_list <- map2(files, new_names, drive_rename)We use purrr::map2_df() to work through the list of dribbles (= Drive files) and the vector of new names and row bind the returned dribbles into a single dribble holding all files. In commented out code, we show an alternative using purrr::map2() that would return another list of dribbles. This would set you up better for downstream operations that required more map()ing.
Let’s check on the contents of this folder again:
drive_ls(folder)
#> # A tibble: 4 x 3
#> name id drive_resource
#> * <chr> <chr> <list>
#> 1 2018-10-05_chicken.txt 1fVtjsxBX62XLMrlRZGdZUbnsKxScbs6j <list [39]>
#> 2 2018-10-05_chicken.pdf 1Tb6OYg7tknLclgjGD_7wiqX2_MB951j9 <list [39]>
#> 3 2018-10-05_chicken.jpg 1PtMTFqV6Mj5HBuSqgZ8C8F3pHu_5SFTw <list [40]>
#> 4 2018-10-05_chicken.csv 1OTsuUqQ_1PjJ1g1xg-IacIry7hdzCU88 <list [38]>Note that you can always row bind individual dribbles into one big dribble yourself. We demo that with dplyr::bind_rows():
bind_rows(files)
#> # A tibble: 4 x 3
#> name id drive_resource
#> <chr> <chr> <list>
#> 1 chicken.csv 1OTsuUqQ_1PjJ1g1xg-IacIry7hdzCU88 <list [38]>
#> 2 chicken.jpg 1PtMTFqV6Mj5HBuSqgZ8C8F3pHu_5SFTw <list [40]>
#> 3 chicken.pdf 1Tb6OYg7tknLclgjGD_7wiqX2_MB951j9 <list [38]>
#> 4 chicken.txt 1fVtjsxBX62XLMrlRZGdZUbnsKxScbs6j <list [38]>Our trashing function, drive_trash() is vectorized and can therefore operate on a multi-file dribble. We could trash these files like so:
If you’re absolutely sure of yourself and happy to do something irreversible, you could truly delete these files with drive_rm(), which is also vectorized:
Finally – and this is the code we will actually execute – the easiest way to delete these files is to delete their enclosing folder.