R Markdown produces reproducible reports combining code, output, and prose. Shiny builds interactive web applications from R. Today covers both — the tools that turn R analysis into deliverable products.
An .Rmd file combines YAML header (title, author, output format), prose (Markdown), and R code chunks (```{r}...```). knit() executes all chunks and renders the result to HTML, PDF, Word, or slides. Inline code: `r round(mean(x), 2)` embeds R output in prose. Parameters make reports dynamic: users change values without editing code. R Markdown is standard for academic papers, business reports, and data science documentation.
Shiny apps have two parts: ui (the layout and input/output elements) and server (the reactive logic). Input widgets: sliderInput, selectInput, textInput, dateRangeInput, fileInput. Output renderers: renderPlot, renderTable, renderText, renderUI. Reactive expressions (reactive(), observe(), eventReactive()) re-execute when inputs change. Deploy to shinyapps.io (free tier available) or self-host with Shiny Server.
R is slow for loops — vectorize everything, or use Rcpp to call C++ from R for hot loops. The future package parallelizes code across CPU cores. data.table is 10-100x faster than dplyr for large datasets (>1M rows). Package development: devtools, roxygen2 for documentation, testthat for tests. CRAN has 20,000+ packages; Bioconductor adds 2,000+ bioinformatics packages.
# Shiny app: interactive histogram
library(shiny)
library(ggplot2)
ui <- fluidPage(
titlePanel('Distribution Explorer'),
sidebarLayout(
sidebarPanel(
selectInput('dataset', 'Dataset',
choices = c('mtcars', 'iris', 'diamonds')),
selectInput('variable', 'Variable', choices = NULL),
sliderInput('bins', 'Bins', min=5, max=50, value=20)
),
mainPanel(
plotOutput('histogram'),
verbatimTextOutput('stats')
)
)
)
server <- function(input, output, session) {
dataset <- reactive({ get(input$dataset) })
observeEvent(input$dataset, {
nums <- names(Filter(is.numeric, dataset()))
updateSelectInput(session, 'variable', choices = nums)
})
output$histogram <- renderPlot({
req(input$variable)
x <- dataset()[[input$variable]]
ggplot(data.frame(x=x), aes(x)) +
geom_histogram(bins=input$bins, fill='steelblue', color='white') +
theme_minimal()
})
output$stats <- renderPrint({
req(input$variable)
summary(dataset()[[input$variable]])
})
}
shinyApp(ui, server)
Build a complete Shiny app that: loads a CSV uploaded by the user, allows column selection for X and Y axes, shows a ggplot2 scatter plot with regression line, displays summary statistics, and lets users download the plot as PDF.