knitr::opts_chunk$set( collapse = TRUE, comment = "#>", echo = TRUE, eval = FALSE )
AI-powered statistical analysis code generation module for jsmodule package.
The AI Assistant module provides an interactive chat interface that generates R code for statistical analysis. It integrates seamlessly with jsmodule's gadgets and supports multiple AI providers (Anthropic Claude, OpenAI GPT, Google Gemini).
Add your API key to .Renviron file:
# Open .Renviron file usethis::edit_r_environ() # Add one of the following lines: # ANTHROPIC_API_KEY=your_key_here # OPENAI_API_KEY=your_key_here # GOOGLE_API_KEY=your_key_here # Save and restart R session
library(jsmodule) # Launch gadget with AI Assistant included jsBasicGadget() # Navigate to "AI Assistant" tab
library(shiny) library(jsmodule) library(survival) ui <- fluidPage( titlePanel("AI Statistical Assistant"), aiAssistantUI("ai") ) server <- function(input, output, session) { data <- reactive(colon) data.label <- reactive(jstable::mk.lev(colon)) callModule(aiAssistant, "ai", data = data, data_label = data.label ) } shinyApp(ui, server)
data parameterout in generated codeGenerated code can only use these packages:
jstable, jskm, jsmodule, survival, ggplot2, ggpubr, pROC, data.table, DT, gridExtra, GGally, forestploter, MatchIt, timeROC
The module automatically generates variable structure information:
- Factor variables
- Numeric variables
- Custom structures (if provided via data_varStruct parameter)
api_key argument in callModule()show_api_config = TRUE).Renviron file)The show_api_config parameter controls how API keys are managed:
show_api_config = TRUE (Default).Renviron file# Development mode - users can configure in UI aiAssistantUI("ai", show_api_config = TRUE) # Default callModule(aiAssistant, "ai", data = data, data_label = data.label, show_api_config = TRUE )
show_api_config = FALSE.Renviron file or explicit api_key argument# Production mode - API key from .Renviron only aiAssistantUI("ai", show_api_config = FALSE) callModule(aiAssistant, "ai", data = data, data_label = data.label, show_api_config = FALSE )
server <- function(input, output, session) { data <- reactive(lung) data.label <- reactive(jstable::mk.lev(lung)) # Define custom variable roles var_struct <- reactive({ list( variable = names(lung), Base = c("age", "sex", "ph.ecog"), Event = "status", Time = "time" ) }) callModule(aiAssistant, "ai", data = data, data_label = data.label, data_varStruct = var_struct ) }
Provide background information to improve AI responses:
callModule(aiAssistant, "ai", data = data, data_label = data.label, analysis_context = reactive({ "NCCTG lung cancer trial data. Primary outcome: time to death (status/time). Focus on performance status (ph.ecog) as predictor." }) )
Hide API configuration UI for production:
ui <- fluidPage( aiAssistantUI("ai", show_api_config = FALSE) ) server <- function(input, output, session) { callModule(aiAssistant, "ai", data = data, data_label = data.label, show_api_config = FALSE # Use only .Renviron ) }
Problem: "API key not configured" error
Solution:
.Renviron file has correct variable name.RenvironSys.getenv("ANTHROPIC_API_KEY"))Problem: Generated code fails to execute
Solution:
Problem: summary() results split into many pieces
Solution: This is now fixed in the latest version. Update jsmodule package.
Problem: \n visible instead of line breaks
Solution: This is now fixed in the latest version. Update jsmodule package.
❌ Bad: "analyze this data"
✅ Good: "perform linear regression with wt.loss as outcome and age, sex, ph.ecog as predictors"
Always review code in the editor before clicking "Run Code"
Use analysis_context parameter to give AI background about your data
Ask follow-up questions to refine code rather than starting over
Q: "Create a Table 1 comparing baseline characteristics by treatment group (rx)"
Q: "Perform Cox regression with time and status as survival outcome,
adjusting for age, sex, and ph.ecog"
Q: "Create a Kaplan-Meier plot stratified by treatment group with risk table"
Q: "Check VIF for multicollinearity in the linear model with wt.loss ~ age + sex + ph.ecog"
The AI Assistant module implements environment-aware code execution to balance security and usability:
Development Mode (Default):
- Uses standard eval() for code execution
- Easier debugging and development
- All console output visible
- Suitable for local, trusted environments
Production Mode:
- Uses RAppArmor::eval.secure() for sandboxed execution (Linux only)
- Enhanced security with resource limits:
- 1GB RAM limit
- 1MB file size limit
- 10 second timeout
- No new process creation
- Prevents system command execution
- Required for public deployments
Environment Detection: The module automatically detects production environments using:
DEPLOYMENT_ENV environment variable (production or development).production marker fileSetting Deployment Mode:
For local development (default):
# No setup needed - defaults to development mode # Or explicitly set in .Renviron: # DEPLOYMENT_ENV=development
For production deployment:
# Add to .Renviron file: # DEPLOYMENT_ENV=production
Or create a marker file:
# In your app directory
touch .production
Linux Server Setup (for RAppArmor):
# Install AppArmor sudo apt-get install apparmor apparmor-utils libapparmor-dev # Install R package R -e "install.packages('RAppArmor')"
Platform Support:
⚠️ IMPORTANT: API Key Handling
How API Keys are Used:
.Renviron) or UI inputhttr package to AI provider APIsThis is Open Source:
✅ What this module does NOT do with API keys:
✅ What IS sent to AI providers:
NOT sent:
For Personal/Desktop Use (Recommended):
# Store API key in .Renviron (user's home directory) # This keeps the key private to your user account # ANTHROPIC_API_KEY=your_key_here
For Team/Shared Use:
.Renvironshow_api_config = TRUE to allow individual configurationFor Public Web Applications:
show_api_config = TRUE publicly.Renviron file (Recommended for personal use):~/.Renviron (user home directory)Persistence: Survives R session restarts
UI Input (Development only):
Persistence: No - must re-enter each session
api_key argument (Advanced use):
If you're working with sensitive data:
For Maximum Security:
# 1. Store API key in .Renviron (never in code) usethis::edit_r_environ() # Add: ANTHROPIC_API_KEY=your_key # 2. Use show_api_config = FALSE in production aiAssistantUI("ai", show_api_config = FALSE) # 3. Never commit .Renviron to version control # Add to .gitignore: # .Renviron # .Renviron.local # 4. Rotate API keys regularly (every 90 days recommended) # 5. Monitor API usage through provider's dashboard
For issues or feature requests, please file an issue at: https://github.com/jinseob2kim/jsmodule/issues
Same as jsmodule package license.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.