Summary
Check that you can select and replace parts of an object by position, name, or condition, while checking the structure of the result.
Before you start: vectors, tables, matrices and lists.
Setup: No data files are needed. Run each object definition before its indexing examples.
Your check: Filter known measurements and change a chosen value in a copy. Practise in the unit summary.
What you learned
| Task | Syntax | Remember |
|---|---|---|
| Select vector elements | x[c(1, 3)] |
R positions start at 1. |
| Exclude vector elements | x[-2] |
Do not mix positive and negative positions, except zero. |
| Select by a condition | x[x > 10] |
The condition produces a logical vector. Handle missing values explicitly. |
| Select a matrix or data-frame rectangle | x[rows, columns] |
The comma separates the two dimensions; a blank selects all entries in that dimension. |
| Keep a one-column table | df[, "height", drop = FALSE] |
Without drop = FALSE, selecting one column this way can return a vector. |
| Select one list component | x[[1]] or x[["name"]] |
x[1] instead returns a list containing that component. |
| Select a named component | df$height |
Convenient for a known column name; use df[[column_name]] if the name is stored in a variable. |
For a data frame, df["height"] selects a column as a data frame; df[1, ] selects a row. For a matrix, a single index such as m[3] counts through columns. Always consider the object’s structure before interpreting brackets.
which() returns positions that meet a condition. %in% tests membership, while match() finds positions of matches. Use &, |, and ! for element-by-element AND, OR, and NOT. Test equality with ==; <- assigns a value.
A short recap in R
observations <- data.frame(
site = c("A", "B", "C", "D"),
height_cm = c(12, NA, 18, 9)
)
keep <- !is.na(observations$height_cm) & observations$height_cm >= 12
selected <- observations[keep, c("site", "height_cm"), drop = FALSE]
selected
The result contains sites A and C, with heights 12 and 18 cm. The explicit !is.na() check excludes the missing measurement. A comparison with an NA alone can leave NA entries in a logical index and produce missing rows in the result.
You can also put an indexed expression on the left of <- to replace selected values. Check the selection first so that you change the intended entries. subset() provides another way to select rows and columns; sample() selects a random sample. Use set.seed() when an example’s random selection needs to be reproducible.
Try it yourself
Use the table below. Select known temperatures of at least 10 °C, excluding site W; retain a table with columns site and temperature_c. Then make a copy of the original table and change only site E’s temperature to 13 °C. Check that the original is unchanged.
readings <- data.frame(site = c("N", "S", "E", "W"),
temperature_c = c(7, NA, 12, 15))
Expected selection: one row, site E at 12 °C; the modified copy has E at 13 °C and retains all four rows.
Hint
Combine the known-value check, comparison and site exclusion with &. Put the row condition before the comma. Assign the original table to a new name before replacing a value.
Compare a possible solution
keep <- !is.na(readings$temperature_c) &
readings$temperature_c >= 10 & readings$site != "W"
chosen <- readings[keep, c("site", "temperature_c"), drop = FALSE]
changed <- readings
changed$temperature_c[changed$site == "E"] <- 13
chosen
dim(chosen)
changed
readings
dim(chosen) is 1 2; the S measurement remains missing in both full tables. Selecting and inspecting the intended row before replacement helps avoid changing another observation.
Ready to continue: you can select by position/name/condition, replace a chosen value and check the result’s structure.
Check your understanding
Try these questions before opening the suggested answers.
- Explain the difference between
observations[1, ]andobservations[, 1]. - How would you select only site C using its name rather than its row number?
- Why do
my_list[1]andmy_list[[1]]sometimes give very different results?
Suggested answers
observations[1, ]selects the first row;observations[, 1]selects the first column and normally returns a vector. Usedrop = FALSEwhen you need a one-column data frame.- Use
observations[observations$site == "C", , drop = FALSE]. Here the site labels contain no missing values. A name-based condition keeps its meaning after row reordering. - Single brackets return a list containing the selected component. Double brackets extract that component, which may itself be a vector, data frame or another list.
Revisit indexing and subsetting for more examples.