R Academy · Lesson

Creating and Inspecting Environments

Use new.env(), environment(), ls(), and get() to work with environments.

Lesson 4 of 413 steps

Creating and Inspecting Environments is a free R Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, and your progress syncs across the web and the CoddyKit app. The R Academy course includes 4 lessons in total.

Creating a New Environment

new.env(parent = e) creates a new empty environment. The parent argument sets which environment is searched when a name is not found in the new one. Use emptyenv() for a fully isolated environment.

# Isolated environment (no parent chain)
e1 <- new.env(parent = emptyenv())
# Environment with global as parent
e2 <- new.env(parent = globalenv())
cat('e1 parent:', environmentName(parent.env(e1)), '\n')
cat('e2 parent:', environmentName(parent.env(e2)), '\n')

assign() — Add Bindings

assign('name', value, envir = e) creates or updates a named binding in the specified environment. It is the programmatic equivalent of e$name <- value, but works when the name is stored in a variable.

e <- new.env(parent = emptyenv())
assign('x', 10, envir = e)
assign('y', 'hello', envir = e)
assign('z', TRUE, envir = e)
cat('x:', get('x', envir = e), '\n')
cat('y:', get('y', envir = e), '\n')

get() and mget()

get('name', envir = e) retrieves a single binding. mget(c('a','b'), envir = e) retrieves multiple bindings at once, returning a named list. Both throw an error if the name does not exist (unless inherits allows chain searching).

e <- new.env(parent = emptyenv())
e$alpha <- 1
e$beta  <- 2
e$gamma <- 3
# Single
get('alpha', envir = e)
# Multiple
mget(c('alpha', 'beta', 'gamma'), envir = e)

ls() — List Bindings

ls(envir = e) returns a character vector of all names bound in environment e. Add all.names = TRUE to include names starting with . (hidden by default). The names are returned in alphabetical order.

e <- new.env(parent = emptyenv())
e$b_val  <- 2
e$a_val  <- 1
e$.secret <- 'hidden'
cat('Default ls:', ls(envir = e), '\n')
cat('All names :', ls(envir = e, all.names = TRUE), '\n')

exists() with inherits

exists('name', envir = e, inherits = FALSE) checks only the specified environment, not its parents. With inherits = TRUE (default), it also searches the parent chain. Use inherits = FALSE for strict local checks.

parent_e <- new.env(parent = emptyenv())
parent_e$shared <- 42
child_e  <- new.env(parent = parent_e)
# inherits=TRUE: finds shared in parent
cat('inherits TRUE:', exists('shared', envir = child_e, inherits = TRUE),  '\n')
# inherits=FALSE: only looks in child
cat('inherits FALSE:', exists('shared', envir = child_e, inherits = FALSE), '\n')

environmentName() and parent.env()

environmentName(e) returns the name of a built-in environment ('R_GlobalEnv', 'package:base', etc.). User-created environments return ''. parent.env(e) returns the parent environment object.

e <- new.env(parent = globalenv())
cat('Name of e     :', environmentName(e), '\n')
cat('Parent of e   :', environmentName(parent.env(e)), '\n')
cat('Name of global:', environmentName(globalenv()), '\n')

$ Syntax for Environments

Environments support the $ and [[ syntax like lists for reading and writing bindings. This is often more convenient than get()/assign() for direct access when the name is known at write time.

e <- new.env(parent = emptyenv())
e$pi_approx <- 3.14159
e[['e_approx']] <- 2.71828
cat('pi:', e$pi_approx, '\n')
cat('e :', e[['e_approx']], '\n')

rm() in a Specific Environment

rm('name', envir = e) removes a binding from a specific environment. This is different from removing a global variable — you must specify the environment explicitly when working with custom environments.

e <- new.env(parent = emptyenv())
e$keep <- 1
e$remove_me <- 99
cat('Before:', ls(envir = e), '\n')
rm('remove_me', envir = e)
cat('After :', ls(envir = e), '\n')

as.list() to Dump an Environment

as.list(e) converts all bindings in an environment to a named list, making it easy to inspect or serialize the contents. The result is a snapshot — later changes to the environment are not reflected in the list.

e <- new.env(parent = emptyenv())
e$x <- 10
e$y <- 20
e$z <- 30
bindings <- as.list(e)
cat('Class:', class(bindings), '\n')
cat('Length:', length(bindings), '\n')
str(bindings)

Environments as Hash Tables

The hash = TRUE option in new.env() (default when parent is set) enables hash-based lookup, making name lookup O(1). This makes large environments much faster than lists for key-value storage.

# Build a small key-value store
store <- new.env(hash = TRUE, parent = emptyenv())
keys   <- paste0('key_', 1:5)
values <- c(10, 20, 30, 40, 50)
for (i in seq_along(keys)) assign(keys[i], values[i], envir = store)
# Retrieve
cat('key_3 =', get('key_3', envir = store), '\n')
cat('All keys:', ls(store), '\n')

Copying vs Sharing Environments

Assigning an environment to a new variable does not copy it — both variables reference the same object. Use as.list() then list2env() to make a true copy if you need independent environments.

e1 <- new.env(parent = emptyenv())
e1$val <- 100
e2 <- e1          # reference, not a copy
e2$val <- 999
cat('e1$val:', e1$val, '\n')  # 999, modified via e2!

# True copy:
e3 <- list2env(as.list(e1), parent = emptyenv())
e3$val <- 0
cat('e1$val after e3 change:', e1$val, '\n')  # still 999

Quick Check

Which function checks if a name is bound in an environment without searching its parent environments?

Creating Environments: Key Takeaways

Key takeaways for creating and inspecting environments:

  • new.env(parent=e) creates a new empty environment; hash=TRUE for large stores
  • assign('x', v, envir=e) and get('x', envir=e) for programmatic access
  • e$x and e[['x']] work like list accessors
  • ls(envir=e) lists names; exists('x', envir=e, inherits=FALSE) for strict check
  • as.list(e) dumps to a list; list2env() reconstructs
  • Environments are reference objects — assignment shares, not copies
config <- new.env(hash = TRUE, parent = emptyenv())
assign('host', 'localhost', envir = config)
assign('port', 5432L,       envir = config)
assign('db',   'mydb',      envir = config)
cat('Keys  :', ls(config), '\n')
cat('host  :', config$host, '\n')
cat('port  :', config$port, '\n')
Free to start

Learn R with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
43
Lessons
159

Frequently Asked Questions

Is the “Creating and Inspecting Environments” lesson free?

Yes — any 3 lessons of the R Academy learning path, including “Creating and Inspecting Environments”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The R Academy course includes 4 lessons in total.

What will I learn in “Creating and Inspecting Environments”?

Use new.env(), environment(), ls(), and get() to work with environments. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start R Academy?

No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Creating and Inspecting Environments” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this R Academy lesson?

Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. What Is an Environment in R?
  2. Lexical Scoping Rules
  3. Global vs Local Scope
  4. Creating and Inspecting Environments
← Back to R Academy