Some googledrive functions are built to naturally handle multiple files, while others operate on a single file.

Functions that expect a single file:

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.

Upload multiple files, then rename them

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.

#> + ggplot2 2.2.1             Date: 2017-09-23
#> + tibble  1.3.4                R: 3.4.1
#> + tidyr   0.7.1               OS: macOS Sierra 10.12.6
#> + readr   1.1.1              GUI: X11
#> + purrr      Locale: en_CA.UTF-8
#> + dplyr   0.7.3               TZ: America/Vancouver
#> + stringr 1.2.0           
#> + forcats 0.2.0
#> ── Conflicts ────────────────────────────────────────────────────
#> * collapse(),  from dplyr, masks glue::collapse()
#> * filter(),    from dplyr, masks stats::filter()
#> * lag(),       from dplyr, 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.

local_files <- drive_example() %>% 

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")
#> Auto-refreshing stale OAuth token.
#> 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:
#> # A tibble: 4 x 3
#>          name                           id drive_resource
#> *       <chr>                        <chr>         <list>
#> 1 chicken.txt 0B0Gh-SuuA2nTdWM5a2lWMnBWcG8    <list [37]>
#> 2 chicken.pdf 0B0Gh-SuuA2nTV1A5T2xEVGdkX3c    <list [37]>
#> 3 chicken.jpg 0B0Gh-SuuA2nTZUN5TW9UUjdXMEE    <list [39]>
#> 4 chicken.csv 0B0Gh-SuuA2nTVk12Y0twb1lDRFU    <list [37]>


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 -> 2017-09-23_chicken.csv
#> File renamed:
#>   * chicken.jpg -> 2017-09-23_chicken.jpg
#> File renamed:
#>   * chicken.pdf -> 2017-09-23_chicken.pdf
#> File renamed:
#>   * chicken.txt -> 2017-09-23_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:

#> # A tibble: 4 x 3
#>                     name                           id drive_resource
#> *                  <chr>                        <chr>         <list>
#> 1 2017-09-23_chicken.txt 0B0Gh-SuuA2nTdWM5a2lWMnBWcG8    <list [38]>
#> 2 2017-09-23_chicken.pdf 0B0Gh-SuuA2nTV1A5T2xEVGdkX3c    <list [38]>
#> 3 2017-09-23_chicken.jpg 0B0Gh-SuuA2nTZUN5TW9UUjdXMEE    <list [39]>
#> 4 2017-09-23_chicken.csv 0B0Gh-SuuA2nTVk12Y0twb1lDRFU    <list [37]>

Note that you can always row bind individual dribbles into one big dribble yourself. We demo that with dplyr::bind_rows():

#> # A tibble: 4 x 3
#>          name                           id drive_resource
#>         <chr>                        <chr>         <list>
#> 1 chicken.csv 0B0Gh-SuuA2nTVk12Y0twb1lDRFU    <list [37]>
#> 2 chicken.jpg 0B0Gh-SuuA2nTZUN5TW9UUjdXMEE    <list [39]>
#> 3 chicken.pdf 0B0Gh-SuuA2nTV1A5T2xEVGdkX3c    <list [37]>
#> 4 chicken.txt 0B0Gh-SuuA2nTdWM5a2lWMnBWcG8    <list [37]>

Clean up

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.

#> Files deleted:
#>   * upload-into-me-article-demo: 0B0Gh-SuuA2nTV2hRTEhqWmdKWGM