title: Mapdist with departure_time: Invalid request
body: <p>I tried to edit the code of @pdx (in the question <a href="https://stackoverflow.com/questions/36936878/how-to-integrate-google-distance-matrix-api-key-in-r-code/37163518?noredirect=1#comment62155804_37163518">How to integrate Google Distance Matrix API key in R code?</a> ) in order to include <code>traffic_mode</code> and <code>departure_time</code>. </p>
  
  <p>The error I get is the following: </p>
  
  <blockquote>
    <p>Invalid request. Missing the 'departure_time' parameter.</p>
  </blockquote>
  
  <p>This is the code:</p>
  
  <pre><code>#' Compute map distances using Google
  #'
  #' Compute map distances using Google Maps. Note that in most cases
  #' by using this function you are agreeing to the Google Maps API
  #' Terms of Service at https://developers.google.com/maps/terms.
  #'
  #' @param from name of origin addresses in a data frame (vector
  #'   accepted)
  #' @param to name of destination addresses in a data frame (vector
  #'   accepted)
  #' @param output amount of output
  #' @param mode driving, bicycling, or walking
  #' @param messaging turn messaging on/off
  #' @param sensor whether or not the geocoding request comes from a
  #'   device with a location sensor
  #' @param language language
  #' @param departure_time number
  #' @param traffic_model
  #' @param override_limit override the current query count
  #'   (.GoogleDistQueryCount)
  #' @return a data frame (output="simple") or all of the geocoded
  #'   information (output="all")
  #' @author David Kahle \email{david.kahle@@gmail.com}
  #' @details if parameters from and to are specified as geographic
  #'   coordinates, they are reverse geocoded with revgeocode.  note
  #'   that the google maps api limits to 2500 element queries a day.
  #' @seealso
  #' \url{http://code.google.com/apis/maps/documentation/distancematrix/}
  #'
  #' @export
  #' @examples
  #'
  #' \dontrun{ online queries draw R CMD check times
  #'
  #' mapdist("waco, texas", "houston, texas")
  #'
  #' from &lt;- c("houston, texas", "dallas")
  #' to &lt;- "waco, texas"
  #' mapdist(from, to)
  #' mapdist(from, to, mode = "bicycling")
  #' mapdist(from, to, mode = "walking")
  #'
  #' from &lt;- c("houston", "houston", "dallas")
  #' to &lt;- c("waco, texas", "san antonio", "houston")
  #' mapdist(from, to)
  #'
  #'
  #' # geographic coordinates are accepted as well
  #' (wh &lt;- as.numeric(geocode("the white house, dc")))
  #' (lm &lt;- as.numeric(geocode("lincoln memorial washington dc")))
  #' mapdist(wh, lm, mode = "walking")
  #' distQueryCheck()
  #'
  #' }
  #'
  mapdist &lt;- function(from, to, mode =     c("driving","walking","bicycling"),
                  output = c("simple","all"), messaging = FALSE, sensor =     FALSE,
                  language = "en-EN",     departure_time='1464926400',traffic_model= "optimistic", override_limit =     FALSE, key)
  {
  
    message("by using this function you are agreeing to the terms at :")
    message("http://code.google.com/apis/maps/documentation/distancematrix/\n")
  
    # check parameters
    if(is.numeric(from) &amp;&amp; length(from) == 2) from &lt;- revgeocode(from)
    stopifnot(is.character(from))
    if(is.numeric(to) &amp;&amp; length(to) == 2) to &lt;- revgeocode(to)
    stopifnot(is.character(to))
    from_to_df &lt;- data.frame(from = from, to = to, stringsAsFactors =     FALSE)
    origins &lt;- from_to_df$from
    destinations &lt;- from_to_df$to # this ensures # from = # to
    mode &lt;- match.arg(mode)
    output &lt;- match.arg(output)
    stopifnot(is.logical(messaging))
    stopifnot(is.logical(sensor))
  
  
    getdists &lt;- function(df){
  
  # format url
  origin &lt;- df$from[1]
  origin &lt;- gsub(",", "", origin)
  origin &lt;- gsub(" ", "+", origin)
  origin &lt;- paste("origins=", origin, sep = "")
  destinations &lt;- df$to
  destinations &lt;- gsub(",", "", destinations)
  destinations &lt;- gsub(" ", "+", destinations)
  destinations &lt;- paste("destinations=", paste(destinations, collapse =     "|"), sep = "")
  mode4url &lt;- paste("mode=", mode, sep = "")
  lang4url &lt;- paste("language=", language, sep = "")
  departure4url &lt;- paste("departure_time=", departure_time, sep = "")
  trans4url &lt;- paste("traffic_model=", traffic_model, sep="")
  sensor4url &lt;- paste("sensor=", tolower(as.character(sensor)), sep = "")
  keyUrl &lt;- paste("key=", key, sep = "")
  posturl &lt;- paste(origin, destinations, mode4url, trans4url, sensor4url,     keyUrl, sep = "&amp;")
  url_string &lt;-     paste("https://maps.googleapis.com/maps/api/distancematrix/json?",
                      posturl, sep = "")
  url_string &lt;- URLencode(url_string)
  
  
  # check if query is too long
  if(nchar(url_string) &gt;= 2048){
    n &lt;- nrow(df)
    half_df &lt;- floor(n/2)
    return(
      rbind(
        getdists(df[half_df,]),
        getdists(df[(half_df+1):n,])
      )
    )
  }
  
  # check/update google query limit
  check_dist_query_limit(url_string, elems = nrow(df),
                         override = override_limit, messaging =     messaging)
  
  
  # distance lookup
  if(messaging) message("trying url ", url_string)
  connect &lt;- url(url_string)
  tree &lt;- fromJSON(paste(readLines(connect), collapse = ""))
  close(connect)
  
  # message user
  message(paste0("Information from URL : ", url_string))
  
  # label destinations - first check if all were found
  if(length(df$to) != length(tree$destination_addresses)){
    message("matching was not perfect, returning what was found.")
    names( tree$rows[[c(1,1)]] ) &lt;- tree$destination_addresses
    output &lt;&lt;- "all"
    # stringdist::amatch(df$to, tree$destination_addresses, maxDist = 10)
  } else {
    names( tree$rows[[c(1,1)]] ) &lt;- df$to
  }
  
      # return
      tree$rows[[c(1,1)]]
    }
  
    out &lt;- dlply(from_to_df, "from", getdists)
  
    # return all
    if(output == "all") return(out)
  
  
  
    # format output
    out &lt;-
  ldply(out, function(oneFromList){
    ldply(oneFromList, function(oneToList){
      data.frame(
        m = oneToList$distance$value,
        km = oneToList$distance$value/1000,
        miles = 0.0006214 * oneToList$distance$value,
        seconds = oneToList$duration$value,
        minutes = oneToList$duration$value / 60,
        hours = oneToList$duration$value / 3600
      )
    })
      })
  
    names(out) &lt;- c("from", "to", names(out)[3:ncol(out)])
  
    # "simple" return
    suppressMessages(join(from_to_df, out))
  }
  
  
  
  
  check_dist_query_limit &lt;- function(url_string, elems, override,     messaging){
    .GoogleDistQueryCount &lt;- NULL; rm(.GoogleDistQueryCount); # R CMD     check trick
  
    if(exists(".GoogleDistQueryCount", .GlobalEnv)){
  
      .GoogleDistQueryCount &lt;&lt;-
        subset(.GoogleDistQueryCount, time &gt;= Sys.time() - 24*60*60)
  
      # 2500 per 24 hours
      if(sum(.GoogleDistQueryCount$elements) + elems &gt; 2500){
    message("query max exceeded, see ?mapdist.  current total = ",
            sum(.GoogleDistQueryCount$elements))
    if(!override) stop("google query limit exceeded.", call. = FALSE)
  }
  
  # 100 per 10 seconds
  if(with(.GoogleDistQueryCount,
          sum(elements[time &gt;= Sys.time() - 10]) + elems &gt; 100
  )){
    if(messaging) message("waiting 10 seconds for another 100     queries...", appendLF=F)
    Sys.sleep(10) # can do better
    if(messaging) message(" done")
  }
  
  # append to .GoogleDistQueryCount
  .GoogleDistQueryCount &lt;&lt;- rbind(.GoogleDistQueryCount,
                                  data.frame(time = Sys.time(),  url =     url_string,
                                                 elements = elems,         stringsAsFactors = FALSE)
      )
  
  
    } else {
  
      .GoogleDistQueryCount &lt;&lt;-
    data.frame(time = Sys.time(),  url = url_string,
               elements = elems, stringsAsFactors = FALSE)
  
    }
  }
  
  
  
  #' Check Google Maps Distance Matrix API query limit
  #'
  #' Check Google Maps Distance Matrix API query limit
  #'
  #' @return a data frame
  #' @author David Kahle \email{david.kahle@@gmail.com}
  #' @seealso         \url{http://code.google.com/apis/maps/documentation/distancematrix/}
  #' @export
  #' @examples
  #' distQueryCheck()
  distQueryCheck &lt;- function(){
    .GoogleDistQueryCount &lt;- NULL; rm(.GoogleDistQueryCount); # R CMD     check trick
    if(exists(".GoogleDistQueryCount", .GlobalEnv)){
      remaining &lt;- 2500-sum(
        subset(.GoogleDistQueryCount, time &gt;= Sys.time() -     24*60*60)$elements
  )
  message(remaining, " distance queries remaining.")
    } else {
      remaining &lt;- 2500
      message(remaining, " distance queries remaining.")
    }
    invisible(remaining)
  }
  </code></pre>
  
  <p>My data looks like this:</p>
  
  <pre><code>dput(X11)
  
  structure(list(pickup = c("40.774135%2C-73.8749", "40.773988%2C-73.87485", 
  "40.646821%2C-73.789771", "40.774079%2C-73.87462", "40.645691%2C-73.776686", 
  "40.645434%2C-73.776758", "40.773917%2C-73.872989", "40.641596%2C-73.787964", 
  "40.773691%2C-73.870689", "40.773579%2C-73.870659"), dropoff = c("40.758691%2C-73.961359", 
  "40.786066%2C-73.971041", "40.731959%2C-74.009028", "40.736534%2C-74.008318", 
  "40.759087%2C-73.960889", "40.757562%2C-73.960927", "40.765958%2C-73.94621", 
  "40.783832%2C-73.972058", "40.75586%2C-73.96334", "40.783067%2C-73.984085"
  )), .Names = c("pickup", "dropoff"), row.names = c("1002", "10283", 
  "10629", "896515", "12312", "741575", "40637", "40864", "47772", 
  "47952"), class = "data.frame")
  </code></pre>