How to Use googlesheets to Connect R to Google Sheets

Often I use R to handle large datasets, analyze the data and filter out the data I don’t need.

When all this is done, I usually use write.csv() to print my data off and reopen it in Google Sheets.

My workflow would look something like this:

full_data <- read.csv("some_dataset.csv")
#R analysis ending up with relevant_data
write.csv(relevant_data, "relevant_data.csv")
#continue work in Google Sheets

However, there’s an R package that provides a bridge between your Google account and your R environment: googlesheets.

Using this package we can read data directly from Google, modify it and create new files within our Google Drive.

Step 1: Install googlesheets

install.packages(googlesheets)
library(googlesheets)

Step 2: Authenticate your Google account

Before we can do anything we need to allow google sheets to access our account.
We can do this by running this:

gs_auth(new_user = TRUE)

Have a browser open (Google Chrome worked for me) and it should open a new tab asking you to connect via an account:

Click on an account below this message and then ‘allow’ and it should take you to a page saying it has worked and to go back to R.

You can rerun this command any time you want to change accounts.

Sometimes if you don’t use the token for a while it will run out and you will have to refresh it, which it will initiate automatically if you run a command that requires you to connect to the Google API (i.e. any of the specialised googlesheets functions).

Step 3: See what’s in your Google Account

Calling the function gs_ls() will show you spreadsheets in your account.

gs_ls()
# A tibble: 15 x 10
 sheet_title author perm version updated sheet_key
 1 for googlesheets rforjournali… rw new 2017-12-11 09:44:54 1Y0WCfTW…
 2 Avon and Somerset Septe… rforjournali… rw new 2017-11-19 12:46:55 1TfC5Fs6…
 3 Mid year 2015 UK popula… rforjournali… rw new 2017-10-25 21:19:52 1Vqg560s…
 4 Cleveland 2016-09 rforjournali… rw new 2016-11-26 10:18:16 19xBr8nU…
 5 Rankings of US presiden… rforjournali… rw new 2016-11-08 04:39:55 11PZxq7y…
 6 Tennis #1s rforjournali… rw new 2016-11-06 20:04:42 1Riz8GRs…
 7 Young persons railcard rob.grant rw new 2016-11-06 13:05:55 1XZsjJxu…
 8 Copy of Young persons r… rforjournali… rw new 2016-11-05 18:14:38 1oUpRS-D…
 9 defective rforjournali… rw new 2016-11-05 11:40:30 1jWZBILC…
10 Asylum rforjournali… rw new 2016-10-27 19:04:05 1CRMl2_1…
11 Buses rforjournali… rw new 2016-10-24 20:07:41 1qy9Z-sn…
12 Untitled spreadsheet rforjournali… rw new 2016-10-24 19:22:42 1_f_FI5n…
13 Population rforjournali… rw new 2016-10-24 18:29:17 1rrOQuV5…
14 Drugs rforjournali… rw new 2016-10-18 21:37:29 1UTsnGM6…
15 Food rforjournali… rw new 2016-10-15 13:24:30 1aWEAPR4…

Step 4: Read a spreadsheet

I am going to select the first spreadsheet ‘for googlesheets’ by its title. It’s a selection of 50 random numbers between 0 and 1 (you can recreate this function with runif() in R).

for_gs <- gs_title("for googlesheets")

You can also locate the sheet by the key (the letters, numbers and characters after the /d/ in the URL) for the same result

for_gs <- gs_key("your_key_here")

This gives us a list, which we can turn into a data frame using the gs_read() command.

for_gs_sheet <- gs_read(for_gs)
str(for_gs_sheet)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 50 obs. of 2 variables:
 $ Number.x: num 0.4696 0.1587 0.0949 0.1823 0.0885 ...
 $ Number.y: num 0.67551 0.7041 0.00167 0.51302 0.20114 ...
 - attr(*, "spec")=List of 2
 ..$ cols :List of 2
 .. ..$ Number.x: list()
 .. .. ..- attr(*, "class")= chr "collector_double" "collector"
 .. ..$ Number.y: list()
 .. .. ..- attr(*, "class")= chr "collector_double" "collector"
 ..$ default: list()
 .. ..- attr(*, "class")= chr "collector_guess" "collector"
 ..- attr(*, "class")= chr "col_spec"

Step 5: Modify the spreadsheet

Next up, we modify our spreadsheet using the gs_edit_cells() function.

This function has several arguments that we need to employ to edit our spreadsheet properly.

gs_edit_cells(for_gs, ws = "Sheet1", anchor = "A2", input = c(1,2), byrow = TRUE)

The ws argument refers to the sheet name in the spreadsheet. The anchor argument refers to the cell from which the modification will begin. In my example, I am editing two cells, where the first one will be the anchor cell A2. The byrow argument indicates that the modification will apply horizontally (change to FALSE for vertical editing).

Note that this won’t change our data frame for_gs_sheet that is based on this spreadsheet; just the spreadsheet itself.

Cell A2 now has a value of 1. A3 is 2.

Step 6: Create a Google Sheets file using R

We can create new spreadsheets using this package using gs_new().

We’ll use the mtcars dataset as a test:

gs_new(title = "mtcars", ws_title = "first_sheet", input = mtcars)

It worked, except it didn’t include the rownames, which contains the cars.

That doesn’t matter, we can add them using gs_edit_cells(), changing the byrow argument to FALSE this time.

#register the new mtcars sheet in R
mtcars_sheet <- gs_new(title = "mtcars", ws_title = "first_sheet", input = mtcars)

#insert the rownames vertically in column L
gs_edit_cells(mtcars_sheet, ws = "first_sheet", anchor = "L2", input = rownames(mtcars), byrow = FALSE)

Final thoughts

That was a quick overview of the most basic functions of the google sheets package.

This is a really useful package. A lot of my work involves reading data in Google Sheets either before or after using R.

Googlesheets means I won’t have to bother with read.csv() or write.csv() as much in the future, saving me time.

So thanks to Jenny Bryan for creating it!

12 Comments

  1. SC
    Shara Medina Clarke October 3, 2020

    Hello! I am new using R… Yesterday, I download RStudio.By default the only that I see it is “Repository (CRAN)”. If I wanna use googlesheets to Connect R to Google Sheets; Do I need to install another repository? How can I add another repository?

    Note:
    I am from Puerto Rico; an unincorporated territory of the United States. For that reason, I understand English, but I can’t speak it well. Spanish is my native language, sorry for any spelling or grammatical mistakes.

    Reply
  2. BL
    BRUCE LITTLE March 23, 2020

    As another user commented, this no longer seems to function. There is an updated version of googlesheets (googesheets4) but it does not have the same functions. Are there plans to update the tutorial? It seemed good when reading it over, but no longer works in implementation.

    Reply
  3. TS
    Tamil Selvan February 28, 2020

    Giving error like this in browser

    Sign in with Google temporarily disabled for this app
    This app has not been verified yet by Google in order to use Google Sign In.

    Reply
  4. QY
    qingye yuan June 21, 2019

    This tutorial is very good, thank you

    Reply
  5. S
    Shreyas March 27, 2018

    hi, this is a great post. clearly the package is very useful. But I get the following error – Help me fix it please
    HTTP error 503 on attempt 1 …
    backing off 0.71 seconds, retrying
    HTTP error 503 on attempt 2 …
    backing off 0.98 seconds, retrying
    HTTP error 503 on attempt 3 …
    backing off 5.39 seconds, retrying
    HTTP error 503 on attempt 4 …
    backing off 6.62 seconds, retrying
    Error in function_list[[k]](value) : Service Unavailable (HTTP 503).

    Reply
  6. JM
    just me March 26, 2018

    Will this work on a corporate google account.
    gs_ls() throws this error
    Error in curl::curl_fetch_memory(url, handle = handle) :
    Couldn’t resolve host name

    which is likely due to the security of a corporate gmail

    Reply
  7. JE
    John Epling January 1, 2018

    Very helpful post, thanks. I’m struggling with the last bit of code – in the gs_edit_cells command, you reference the object “mtcars_sheet”, but that doesn’t work for me. I have to re-register the “mtcars” object with gs-title (realized after trying unsuccessfully to reference “mtcars” by itself after creating with gs_new), then use the “mtcars” object with gs_edit_cells. Am I missing something?

    Reply
    1. A
      amr January 2, 2018

      Did you try assigning the gs_new() to the object mtcars_sheet and then use it with gs_edit_cells?

      Reply
      1. JE
        John Epling January 3, 2018

        Thanks. That would definitely be a solution and seems to be what was intended – my main point is that that step should be elicited in the script above…it’s not clear where “mtcars_sheet” object came from.

        Reply
    2. RJ
      R For Journalists January 21, 2018

      Hi John, thanks! No, I was missing something. I forgot to set the mtcars_sheet object before editing the cells. I’ve changed it above now.

      So it should read:

      mtcars_sheet <- gs_new(title = "mtcars", ws_title = "first_sheet", input = mtcars)

      gs_edit_cells(mtcars_sheet, ws = "first_sheet", anchor = "L2", input = rownames(mtcars), byrow = FALSE)

      Rob

      Reply
  8. EB
    Emil Begtrup-Bright December 31, 2017

    You tell a lot abot how to do this, but what is the benefit? Would like to hear you elaborate! regards, Emil

    Reply
    1. RJ
      R For Journalists January 21, 2018

      Hi Emil, usually my workflow is:

      import large files into R -> data analysis -> print off CSVs -> import into Google Sheets for further analysis

      Using the googlesheets package cuts out the exporting and importing of CSVs, like this:

      import into R -> data analysis -> send data to Google directly using the googlesheets package

      It’s up to you if you want to use this package – I’ve found it a bit slow for exporting larger datasets at times but it’s an option to possibly save you time.

      Rob

      Reply

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.