One option is use dplyr
from tidyverse
. I use the function mutate
to alter the columns, which I select by using across
. Since you have a range of columns that are next to each other, then you can just give the first and last column with :
in the middle, which will get all columns in between. Then, I apply a function with ~
to subtract 1 from each value in each column (i.e., .
).
Starting Dataframe
X1 X2 X3 X4 X5 X6 X7 X8
1 3 0 3 8 7 3 2 6
2 1 6 10 1 2 2 5 1
3 10 3 3 10 2 1 6 1
4 7 5 8 10 4 1 3 9
5 4 10 3 7 7 0 0 8
dplyr
library(dplyr)
df %>%
mutate(across(X2:X7, ~ . - 1))
Output
X1 X2 X3 X4 X5 X6 X7 X8
1 3 -1 2 7 6 2 1 6
2 1 5 9 0 1 1 4 1
3 10 2 2 9 1 0 5 1
4 7 4 7 9 3 0 2 9
5 4 9 2 6 6 -1 -1 8
Or if you only want to select certain columns, then you can input the names (as I do below) or column index into c()
.
df %>%
mutate(across(c(X2, X4, X6), ~ . - 1))
Or if you need to apply the function to every column, then you can use everything()
.
df %>%
mutate(across(everything(), ~ . - 1))
The other option as @user20650 provided is to simply use base R and select the columns that you want by index. However, if you want to replace the values in the original dataframe, then you need to assign the new values to the same subset (as @r2evans did above).
df[c(2:7)] <- df[c(2:7)] - 1
Data
df <-
structure(
list(
X1 = c(3L, 1L, 10L, 7L, 4L),
X2 = c(0L, 6L, 3L, 5L, 10L),
X3 = c(3L, 10L, 3L, 8L, 3L),
X4 = c(8L, 1L, 10L, 10L, 7L),
X5 = c(7L, 2L, 2L, 4L, 7L),
X6 = c(3L, 2L, 1L, 1L, 0L),
X7 = c(2L, 5L, 6L, 3L, 0L),
X8 = c(6L, 1L, 1L, 9L, 8L)
),
class = "data.frame",
row.names = c(NA,-5L)
)