How to Use Gemini API in R

llm
gemini
ellmer
Learn to use Google’s Gemini API in R with the ellmer package. Connect to Gemini Pro, create conversations, and build AI-powered R applications.
Published

April 4, 2026

Introduction

Gemini is Google’s most capable AI model. It excels at reasoning, coding, and multimodal tasks (text + images). The ellmer package provides a tidyverse-friendly way to use Gemini’s API in R.

Alternatives: See also OpenAI API, Claude API, or run models locally with Ollama for free.

What you’ll learn:

  • Set up Gemini API access
  • Use ellmer’s chat_gemini() function
  • Create multi-turn conversations
  • Use structured data extraction
  • Compare Gemini models

Getting Started

Install ellmer

install.packages("ellmer")
library(ellmer)

Get your API key

  1. Go to Google AI Studio
  2. Sign in with your Google account
  3. Click “Get API key” in the left sidebar
  4. Create a new API key

Note: Gemini API has a generous free tier for experimentation.

Set your API key

# Option 1: Set for current session
Sys.setenv(GOOGLE_API_KEY = "your-api-key-here")

# Option 2: Add to .Renviron (recommended)
usethis::edit_r_environ()
# Add: GOOGLE_API_KEY=your-api-key-here

Basic Chat

Create a chat session

library(ellmer)

chat <- chat_gemini()
chat$chat("What is R programming?")

Single question

chat <- chat_gemini()
response <- chat$chat("Explain what a data frame is in R.")
response

Specify model

# Use specific Gemini model
chat <- chat_gemini(model = "gemini-2.5-pro")

Available Models

Current Stable Models

Model Best For Context
gemini-2.5-flash Best price-performance, reasoning 1M tokens
gemini-2.5-pro Complex tasks, deep reasoning, coding 1M tokens
gemini-2.5-flash-lite Fastest, most budget-friendly 1M tokens

Latest Preview Models

Model Best For Context
gemini-3.1-pro-preview Advanced intelligence, agentic coding 1M tokens
gemini-3-flash-preview Frontier performance at low cost 1M tokens
gemini-3.1-flash-lite-preview Most economical newest model 1M tokens
# Gemini 2.5 Flash (recommended default)
chat <- chat_gemini(model = "gemini-2.5-flash")

# Gemini 2.5 Pro (most capable stable)
chat <- chat_gemini(model = "gemini-2.5-pro")

# Gemini 3.1 Pro Preview (cutting edge)
chat <- chat_gemini(model = "gemini-3.1-pro-preview")

Note: Gemini models support up to 1M token context windows, ideal for analyzing long documents. Use -preview models for the latest capabilities.

System Prompts

Control Gemini’s behavior:

chat <- chat_gemini(
  system_prompt = "You are an expert R programmer. Always provide working code examples. Be concise."
)

chat$chat("How do I calculate the mean of a column?")

Specialized assistants

# Data analysis assistant
analyst <- chat_gemini(
  system_prompt = "You are a data analyst expert in R and the tidyverse.
  When asked questions, provide clear explanations with code examples."
)

analyst$chat("How do I find outliers in my data?")

Multi-turn Conversations

ellmer maintains conversation history automatically:

chat <- chat_gemini()

# First message
chat$chat("I have a dataset of customer purchases.")

# Follow-up (Gemini remembers context)
chat$chat("How would I calculate total spending per customer?")

# Another follow-up
chat$chat("Now how do I visualize this?")

View conversation history

# See all turns
chat$get_turns()

Practical Examples

Generate R code

chat <- chat_gemini(
  system_prompt = "You are an R expert. Return only executable R code with comments. No explanations outside code."
)

code <- chat$chat("
Create a function that:
1. Takes a data frame and column name
2. Removes outliers (values beyond 1.5*IQR)
3. Returns the cleaned data frame
")

cat(code)

Explain existing code

chat <- chat_gemini()

code_to_explain <- "
mtcars |>
  group_by(cyl) |>
  summarise(across(where(is.numeric), mean)) |>
  pivot_longer(-cyl)
"

chat$chat(paste("Explain this R code step by step:", code_to_explain))

Debug errors

chat <- chat_gemini(
  system_prompt = "You are an R debugging expert. When shown errors, explain the cause and provide a fix."
)

error_message <- "Error in select(df, name) : object 'name' not found"

chat$chat(paste("I got this error:", error_message,
                "My code was: df |> select(name)"))

Structured Output

Extract data in a specific format. For more examples, see How to Extract Structured Data with LLMs.

Define a schema

review_schema <- type_object(
  sentiment = type_string("positive, negative, or neutral"),
  confidence = type_number("confidence score 0-1"),
  summary = type_string("one sentence summary")
)

Extract structured data

chat <- chat_gemini()

result <- chat$extract_data(
  "This product exceeded my expectations! Great quality and fast shipping.",
  type = review_schema
)

Access results

result$sentiment
# "positive"

result$confidence
# 0.95

Streaming Responses

For long responses, stream output:

chat <- chat_gemini()

# Stream response (prints as it generates)
chat$stream("Write a detailed guide to ggplot2 themes.")

Error Handling

safe_chat <- function(prompt) {
  tryCatch({
    chat <- chat_gemini()
    chat$chat(prompt)
  }, error = function(e) {
    message("API Error: ", e$message)
    NA
  })
}

result <- safe_chat("What is 2+2?")

Common errors

Error Cause Solution
401 Unauthorized Invalid API key Check GOOGLE_API_KEY
429 Rate limit Too many requests Add delays
400 Bad request Invalid parameters Check model name

Gemini vs Other Providers

Feature Gemini OpenAI Claude
Context window 1M tokens 128k tokens 1M tokens
Free tier Yes No No
Multimodal Yes Yes Yes
Code quality Good Excellent Excellent
Speed Fast Fast Medium
Latest models Gemini 3.1 GPT-5.4 / o3 Claude 4.6

Choose Gemini when:

  • You need to process very long documents (1M tokens)
  • You want a free tier for experimentation
  • You’re already in the Google ecosystem
  • You need the latest preview models

Batch Processing

Process multiple texts with rate limiting:

library(purrr)

classify_text <- function(text) {
  chat <- chat_gemini(
    system_prompt = "Classify as positive/negative/neutral. One word only."
  )
  Sys.sleep(0.5)  # Rate limiting
  chat$chat(text)
}

texts <- c("Great product!", "Terrible service", "It's okay I guess")

results <- map_chr(texts, classify_text)
# "positive", "negative", "neutral"

Common Mistakes

1. Using wrong API key variable

# Wrong
Sys.setenv(GEMINI_API_KEY = "key")

# Right
Sys.setenv(GOOGLE_API_KEY = "key")

2. Forgetting conversation state

# Each chat_gemini() creates a NEW conversation
chat1 <- chat_gemini()
chat1$chat("My name is Alice")

chat2 <- chat_gemini()  # New conversation!
chat2$chat("What's my name?")  # Gemini doesn't know

# Reuse same chat object for context
chat1$chat("What's my name?")  # "Alice"

3. Not handling rate limits

# Add delays in loops
results <- map(items, \(item) {
  Sys.sleep(0.5)  # Important!
  chat$chat(item)
})

Summary

Task Code
Basic chat chat <- chat_gemini(); chat$chat("Hi")
Set API key Sys.setenv(GOOGLE_API_KEY = "key")
System prompt chat_gemini(system_prompt = "...")
Stable model chat_gemini(model = "gemini-2.5-flash")
Latest model chat_gemini(model = "gemini-3.1-pro-preview")
Structured output chat$extract_data(text, type)
  • Gemini 2.5 models are stable with 1M token context
  • Gemini 3.x preview models offer cutting-edge capabilities
  • Free tier available for experimentation
  • Use system prompts to control response style

Sources