Objectives:
We will use the packages googledrive
and
googlesheets4
to save and load daa from google drive
library(dplyr)
# Install the package if not installed
if(require('googledrive') == F){
install.packages("googledrive")
}
if(require('googlesheets4') == F){
install.packages("googlesheets4")
}
There are a couple of things we need to do to authorize R and our
shiny app to use google sheets. First we will need to allow the session
to catch the authentication information and then use the function
drive_auth()
and gs4_auth()
to log into our
drive. The auth information will be saved in a hidden file called
.secrets, this file must be saved inside the folder that
contains your shiny app.
# to catch the google drive auth must run this code first: ----------------
# This part creates a folder where the auth info will be stored:
options(
# whenever there is one account token found, use the cached token
gargle_oauth_email = TRUE,
# specify auth tokens should be stored in a hidden directory ".secrets"
gargle_oauth_cache = "misc/Code/Checkpoints/IIIa/.secrets"
)
# Then you have to authenticate your credentials for both packages:
googledrive::drive_auth()
googlesheets4::gs4_auth()
# To see the credentials you can use:
list.files("misc/Code/Checkpoints/IIIa/.secrets")
Once the authentication is complete, you should see a message like this in your web browser:
To read files from the drive, you will need the id of the file you
want to access. We can search for files in the drive with the function
drive_find()
, but depending how many files you have, this
could take several minutes. If you are trying to access files from a
shared drive, you can use the argument shared_drive
and
specify the name.
drive_find(pattern = 'GeoLocations', shared_drive = 'ShinyWorkshop')$id
You can also find the id in the link of the file. For example, for the file we want to access (https://docs.google.com/spreadsheets/d/1ct-_meVE9GsIgTNpQa9n3SJKwXBApKAqdZ539xvSqdY), the id would be the last series of numbers: *1ct-_meVE9GsIgTNpQa9n3SJKwXBApKAqdZ539xvSqdY*
To access the file we use the function read_sheet()
and
as argument we specify the id we want to read:
# define the id for the file:
Geolocations <- '1ct-_meVE9GsIgTNpQa9n3SJKwXBApKAqdZ539xvSqdY'
# Load data
dGL <- read_sheet(ss = Geolocations)
dGL
We can sue the function sheet_apend()
to add new rows to
our data. Lets create a data.frame that will be a single row, and then
append this to the google sheet.
data.frame(
Name = 'Location x', # You can try to change the name to something else to see the one you appended
Lat = 18.38841,
Lon = -100.73483
) %>%
sheet_append(ss = Geolocations)
If we go to our google sheet, we will see the new observation we added.
We can also make the changes directly in the google sheet, and the next time we load the data we will see the changes.
Now that we know how to load and write data to google sheets, lets try to incorporate this in shiny.
It is important that the folder that contains your app has the file
we created when authorizing the account, otherwise it will not work when
you upload your app to a server, or run it in another session.
To tell shiny to use the correct auth file you have to add the following
code to the global section of your app:
# add the libraries we will sue:
library(googledrive)
library(googlesheets4)
# Google drive set up
options(
# whenever there is one account token found, use the cached token
gargle_oauth_email = TRUE,
# specify auth tokens should be stored in the hidden directory ".secrets"
gargle_oauth_cache = ".secrets"
)
# Specify the id for the file we will use
Geolocations <- '1ct-_meVE9GsIgTNpQa9n3SJKwXBApKAqdZ539xvSqdY'
Now lets create a few inputs so we can add new entries from our shiny app. We will add a new box to our third tab, this box will include the inputs for the columns we want to fill in our data for each row, and we will also create an action button to submit the information.
box(title = 'Add New Observation', # title of the new box
width = 12,
textInput(inputId = 'NameIn', label = 'Name'),
numericInput(inputId = 'LatIn', label = 'Latitude', value = 0),
numericInput(inputId = 'LonIn', label = 'Longitude', value = 0),
actionButton(inputId = 'submit', label = 'Submit')
)
You should have a box similar to this one:
Now we will do the respective changes in the server to execute the
actions. We will use the function observeEvent()
to react
the submit button we created. Every time the button is clicked it will
do the following:
observeEvent(input$submit, {
showModal(modalDialog("Uploading data", footer=NULL)) #Show first message
data.frame(Name = input$NameIn, # Create the data frame with the entries
Lat = input$LatIn,
Lon = input$LonIn) %>%
sheet_append(ss = Geolocations, data = .) # Append the data
removeModal() # Remove first message box
showModal(modalDialog( # Show message of confirmation
title = "Submision complete",
paste0('Thanks for submiting the information'),
easyClose = TRUE,
footer = NULL
))
})
Try to submit an entry and you should get a message like this one:
Now try to integrate the locations from the google sheets into the app. The idea would be to first create a reactive object that reads the data from google sheets every time new info is submitted, and then this gets added to the leaflet map.