R PROGRAMMING • GETTING STARTED AND TOOLING

Running R Code — Run R code in the console and in an R script (.R)

Master the two fundamental execution modes in R to build reproducible, interactive data analysis workflows.

Historical Context & Motivation

The R programming language grew out of the S language developed at Bell Laboratories in the 1970s, a time when statisticians needed a way to interactively explore data without the rigid compile-link-run cycle of Fortran or C. Ross Ihaka and Robert Gentleman created R in 1993 at the University of Auckland, deliberately designing it around the concept of an interactive console — a read-evaluate-print loop (REPL) that lets users type an expression, see its result immediately, and iterate rapidly. This philosophy of exploratory, conversational computing was a direct inheritance from S and set R apart from the batch-processing paradigm that dominated scientific computing at the time.

1976
S Language at Bell Labs
John Chambers and colleagues develop S, introducing interactive statistical computing with a REPL-based workflow that influenced all subsequent statistical languages.
1993
R is Born
Ross Ihaka and Robert Gentleman release an early version of R at the University of Auckland, preserving S's interactive console paradigm while adding lexical scoping and open-source licensing.
2000
R 1.0 Released
R 1.0.0 is officially released with the R Core Team governance structure. The source() function and .R script convention are already stable, establishing the dual console/script execution model.
2011
RStudio Launches
RStudio (now Posit) releases its integrated development environment, providing a unified interface with a script editor pane and console pane side by side, making the console-to-script workflow seamless.
2020s
Modern R Ecosystem
R supports multiple execution paradigms including R Markdown, Quarto, and Shiny, but the console and .R script remain the foundational building blocks upon which all these systems are constructed.

The central question that this lesson addresses is deceptively simple: when you write R code, how does it actually get executed? R provides two distinct but complementary modes — the interactive console for rapid experimentation and the .R script file for reproducible, versionable programs. Understanding when and how to use each mode is essential for any serious data science or statistical computing work.

Core Principles & Definitions

Before diving into mechanics, it is important to establish the foundational concepts that underpin R's execution model. Whether you are typing directly into a console or running a saved script, R processes your code through the same interpreter — the difference lies in the source of input and the granularity of execution. The four core principles below define the framework you should use to reason about running R code.

1

The REPL (Read-Eval-Print Loop)

R's console implements a REPL: it reads your input, evaluates the expression, prints the result, and loops back for more input. Each expression is processed one at a time.
2

Script as Persistent Code

An .R script is a plain-text file containing a sequence of R expressions. It provides reproducibility, version control compatibility, and the ability to share and rerun analyses exactly.
3

Shared Global Environment

Both the console and scripts operate on the same global environment within a session. Variables created in the console are visible to scripts executed via source(), and vice versa.
4

source() as the Bridge

The source() function reads a .R file and evaluates every expression sequentially in the current session. It is the programmatic equivalent of typing each line into the console.
KEY TAKEAWAY
Think of the R console as a whiteboard — you sketch ideas quickly, test calculations, and erase when done. An R script is like a lab notebook — it captures every step so that you or a collaborator can reproduce the entire analysis later. A productive R workflow constantly moves between both: explore on the whiteboard, commit to the notebook.

Visual Explanation — The R Execution Pipeline

The following diagram illustrates how R code flows from the two input sources — the interactive console and a .R script file — through the R interpreter and into the global environment. Notice that both paths converge at the R interpreter, which is the unified engine that parses, evaluates, and produces output for every expression regardless of its origin.

Both the interactive console (top-left, cyan) and .R script files (bottom-left, violet) feed expressions into the same R interpreter (center, amber). Results flow to the global environment (top-right, emerald) and console output (bottom-right, pink). Side effects such as file writes and plot generation occur as optional by-products.

As the diagram makes clear, the interpreter does not distinguish between code entered interactively and code fed in from a file. The critical distinction is one of workflow: the console processes one expression per iteration of the REPL loop, whereas source() feeds the interpreter a batch of expressions from the file, evaluating them top to bottom. Both paths ultimately write bindings into the same global environment, which is why you can define a variable in a script and then inspect it from the console prompt within the same session.

How It Works — Console vs. Script Execution in Detail

The Interactive Console (REPL)

When you launch R — whether through a terminal, RGui, or the console pane in RStudio — the interpreter enters its REPL cycle. The prompt character > signals that R is in the Read phase, waiting for input. You type an expression such as sqrt(144) and press Enter. The interpreter evaluates the expression, prints the result ([1] 12), and loops back to the prompt. If your expression is incomplete — for instance, you typed 1 + and pressed Enter — R displays the continuation prompt +, indicating it is still in the Read phase and waiting for the rest of the expression.

💡 Console Auto-Printing
In the console, the result of an expression is automatically printed unless you explicitly suppress it with invisible() or assign the result to a variable. For example, typing x <- 5 produces no visible output because the assignment operator returns the value invisibly.

R Scripts (.R Files)

An R script is simply a plain-text file with a .R extension containing one or more R expressions. You create it in any text editor or the source pane of RStudio. There are three primary ways to execute the code within a script. First, from within an R session, you call source("my_script.R"), which reads the file and evaluates every expression sequentially. Second, in RStudio, you can place your cursor on a line (or select a block) and press Ctrl+Enter (Cmd+Enter on macOS) to send that code to the console for evaluation — a hybrid approach that combines the convenience of a script with the immediacy of the console. Third, from a system shell, you can invoke Rscript my_script.R to run the file in a non-interactive, batch mode, which is critical for automated pipelines and cron jobs.

⚠️ Auto-Printing Difference in Scripts
When code runs via source(), bare expressions do not auto-print by default. If your script contains just 42 on a line, nothing appears unless you wrap it in print(42) or call source("file.R", echo = TRUE). This is one of the most common surprises for beginners transitioning from console to script.

The source() Function in Depth

The source() function accepts several useful parameters. The echo argument, when set to TRUE, causes each expression to be printed to the console before evaluation, mimicking interactive behavior. The local argument, when set to TRUE, evaluates the script in a local environment rather than the global one — analogous to function-scoped execution, which prevents the script from polluting the caller's namespace. The encoding argument lets you specify character encoding (commonly "UTF-8"), ensuring cross-platform compatibility.

Detailed Breakdown — Workflow Patterns and Execution Modes

In practice, R programmers do not exclusively use the console or exclusively use scripts — they follow structured workflow patterns that leverage both execution modes at different stages of a project. The diagram below maps these patterns along the lifecycle of a typical data analysis.

The top row shows the four-stage lifecycle: explore interactively in the console, codify working code into a .R script, test the script via source() or line-by-line execution, and finally automate with Rscript for batch processing. The dashed feedback arrow represents the common pattern of returning to the console to debug issues discovered during testing. The bottom comparison panels summarize the key behavioral differences between console and script execution modes.

The most productive R workflows treat the console and script as complementary tools rather than alternatives. A typical session begins with exploratory data analysis (EDA) at the console: loading a dataset, inspecting its structure with str(), generating quick plots, and testing transformations. Once a sequence of commands proves useful, the analyst migrates it into a .R script to ensure reproducibility. The script can then be run end-to-end via source(), or individual sections can be sent to the console for targeted debugging. Finally, for deployment on servers or CI/CD pipelines, the script is invoked via Rscript in a fully non-interactive batch mode.

  • Ctrl+Enter (RStudio) — sends the current line or selection from the script editor to the console for immediate evaluation
  • Ctrl+Shift+Enter (RStudio) — runs the entire script from top to bottom in the console, equivalent to source()
  • Ctrl+Shift+S (RStudio) — sources the current script file (same as typing source("file.R") in the console)

Worked Example — From Console Exploration to .R Script

This worked example walks through a realistic scenario: computing the body mass index (BMI) for a small dataset, starting with interactive exploration and finishing with a reproducible script.

Console to Script: BMI Computation
1
Step 1 — Explore Interactively in the ConsoleOpen R or RStudio. At the console prompt, create two vectors for height (in meters) and weight (in kilograms): > height <- c(1.75, 1.60, 1.82, 1.68) > weight <- c(70, 55, 90, 65) These assignment statements return invisibly, so no output appears. Verify by typing > height, which auto-prints the vector.
[1] 1.75 1.60 1.82 1.68
2
Step 2 — Compute BMI at the ConsoleBMI is weight divided by height squared. R's vectorized operations make this a single expression: > bmi <- weight / height^2 Inspect the result by typing > bmi at the prompt.
[1] 22.857 21.484 27.170 23.030
3
Step 3 — Test a Summary at the ConsoleUse > round(mean(bmi), 2) to compute the group average BMI. The console auto-prints the scalar result immediately.
[1] 23.64
4
Step 4 — Codify into a .R ScriptOpen a new file in RStudio (File → New File → R Script) or any text editor. Save it as bmi_analysis.R. Write the following content: # bmi_analysis.R — Compute and report BMI height <- c(1.75, 1.60, 1.82, 1.68) weight <- c(70, 55, 90, 65) bmi <- weight / height^2 cat("Individual BMIs:", round(bmi, 2), "\n") cat("Mean BMI:", round(mean(bmi), 2), "\n") Note the use of cat() instead of relying on auto-printing, since source() does not auto-print bare expressions.
5
Step 5 — Run the Script via source()Back in the console, execute: > source("bmi_analysis.R") All five lines are evaluated sequentially. The cat() calls produce console output. Alternatively, from a system terminal: $ Rscript bmi_analysis.R This runs R non-interactively and exits when the script completes.
Individual BMIs: 22.86 21.48 27.17 23.03 Mean BMI: 23.64

Console vs. Script — Strengths and Limitations

Choosing between the console and a script is not a binary decision but a matter of context. The table below summarizes the trade-offs across several important dimensions that affect everyday R programming.

Feature comparison between the interactive console and .R script execution
DimensionConsole (REPL).R Script
ReproducibilityLow — history is session-bound and hard to reconstructHigh — the entire analysis is captured in a file
Iteration SpeedVery fast — immediate feedback per expressionModerate — requires re-sourcing or selective execution
Version ControlNot practical — console input is ephemeralExcellent — Git tracks every change to the .R file
Auto-PrintingYes — bare expressions auto-print resultsNo — must use print() or cat() explicitly
CollaborationDifficult — no shareable artifactEasy — scripts can be shared, emailed, or committed to a repository
AutomationNot possible — requires human at the keyboardFully supported — Rscript enables cron jobs and CI/CD
Best ForEDA, debugging, learning, quick calculationsProduction code, reports, automated pipelines, team projects
KEY TAKEAWAY
Think of the relationship between the console and scripts like the relationship between a debugger and source code in compiled languages. The debugger (console) lets you inspect state and test hypotheses in real time, but the source code (script) is what gets committed, reviewed, and deployed. Neither replaces the other; software engineering best practice is to use both throughout the development cycle.

Connection to Advanced Execution Paradigms

The console and .R script form the foundation of R's execution model, but modern R extends these primitives into richer paradigms. Understanding the base layer is essential before moving to these more powerful tools, each of which builds directly on the concepts covered in this lesson.

Advanced R execution paradigms that build on the console and .R script foundation
ParadigmBased OnKey Enhancement
R Markdown (.Rmd)R code chunks embedded in Markdown — each chunk is effectively a mini-scriptLiterate programming: code, output, and narrative woven into a single document (HTML, PDF, Word)
Quarto (.qmd)Next-generation R Markdown supporting R, Python, Julia, and Observable JSCross-language execution with standardized YAML metadata and built-in publishing
Shiny AppsR scripts organized into ui.R, server.R, or a single app.RReactive execution: R code re-runs automatically when user inputs change in a web interface
R PackagesCollections of .R files in the R/ directory, loaded via library()Namespaced environments, documentation, testing, and distribution via CRAN
targets / make pipelinesDAG-based orchestration of R scripts and functionsDependency-aware caching: only re-runs steps whose inputs have changed

Each of these paradigms can be understood as a structured way to organize and trigger the same fundamental operation you have been learning: sending R expressions to the interpreter for evaluation. R Markdown, for instance, extracts code chunks from a document, source()-like evaluates them in order, captures the output, and knits it back into the document. Shiny merely adds a reactive event loop that re-evaluates selected expressions when the user interface signals a change. Mastering the console and script workflow now gives you the mental model needed to reason about all of these tools confidently.

Practice Problems

PROBLEM 1CONCEPTUAL
Explain the difference in auto-printing behavior between typing 42 at the R console and having the line 42 inside a .R script that is executed with source("file.R"). Why does this difference exist, and how would you force the script to produce output?
PROBLEM 2BASIC
Write a three-line R script called greet.R that: (a) assigns your name to a variable name, (b) creates a greeting string using paste0(), and (c) prints it to the console. Then show the exact command to run this script from within an R session.
PROBLEM 3INTERMEDIATE
You have a script helpers.R that defines a function zscore <- function(x) (x - mean(x)) / sd(x). You want to use this function in another script analysis.R. Explain how to set this up, discuss what happens if you call source("helpers.R", local = TRUE) inside analysis.R, and describe the scoping implications.
PROBLEM 4APPLIED
You are deploying an R-based data pipeline on a Linux server. The script etl_pipeline.R reads from a database, transforms data, and writes a CSV. Write the cron job entry that runs this script every day at 2:00 AM, and explain the differences between using Rscript versus R CMD BATCH for this use case.
PROBLEM 5CRITICAL THINKING
A colleague argues that all R work should be done exclusively in scripts for reproducibility, and that the interactive console is an anti-pattern. Construct a nuanced counterargument that acknowledges the value of reproducibility while defending the console's role. Reference specific scenarios where the console provides capabilities that scripts cannot easily replicate.

Lesson Summary

R provides two fundamental code execution modes. The interactive console implements a REPL (read-eval-print loop) that processes one expression at a time, automatically prints results, and provides an immediate feedback loop ideal for exploration, debugging, and learning. The .R script file stores a sequence of expressions in a plain-text file that can be executed via source() within a session, sent line-by-line with Ctrl+Enter in RStudio, or run non-interactively via Rscript for batch automation.

Both modes feed expressions to the same R interpreter and share the same global environment. The key behavioral difference is auto-printing: the console prints results automatically while scripts require explicit print() or cat() calls. The optimal workflow iterates between console-based exploration and script-based codification — explore, codify, test, and automate — forming the foundation upon which advanced paradigms like R Markdown, Quarto, Shiny, and package development are built.

Varsity Tutors • R Programming • Running R Code — Run R code in the console and in an R script (.R)