2

I am super new to R, and the many facets of coding language.

I have a set of data with many variables. I have a few columns (that are beside each other), where I need to subtract 1 from all values in those specific columns. Then, I want to replace the values from the original columns (+1) with the new (-1) values.

AndrewGB
  • 16,126
  • 5
  • 18
  • 49
  • 1
    `df[c(1,2,4)] <- lapply(df[c(1,2,4)], \`-\`, 1)` should do it (those are backticks, not single-quotes, fyi). If you have more that needs to be done, that is shorthand for `lapply(df[c(1,2,4)], function(z) z - 1)`, which should make it clear how to extend if needed. – r2evans Jan 21 '22 at 00:24
  • 3
    i think `df[c(1,2,4)] - 1` is enough? – user20650 Jan 21 '22 at 00:28
  • that too ... I guess I was thinking more extensible and such, but @user20650's is much more direct – r2evans Jan 21 '22 at 00:29

2 Answers2

1

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)
  )
AndrewGB
  • 16,126
  • 5
  • 18
  • 49
  • Thank you so much! However, I am having trouble accessing diplyr. I installed diplyr using this: install.packages('dplyr', repos = 'https://cloud.r-project.org'), and that worked, but for some reason I cannot load it. I've downloaded tidyverse as well. – Cassidy Tomlinson Jan 21 '22 at 01:24
  • @CassidyTomlinson What kind of error message are you getting? You could also just try to do `library(tidyverse)` as that will also load `dplyr` (as it is part of the `tidyverse`). – AndrewGB Jan 21 '22 at 01:32
  • I think I just needed to restart R! – Cassidy Tomlinson Jan 21 '22 at 01:41
  • Actually it says that there are conflicts with diplyr when i tried to load the library of tidyverse – Cassidy Tomlinson Jan 21 '22 at 01:44
  • Not sure; you might have other packages that clash with it. I'm not really sure without seeing specific messages. Sometimes you can get around loading the package by calling the package explicitly with the functions (e.g., `dplyr::mutate`, `dplyr::across`, etc.) – AndrewGB Jan 21 '22 at 04:11
0

Just subtract 1 from selected columns and assign them back. Really no packages needed.

Example:

df
#   X1 X2 X3 X4
# 1  1  1  1  1
# 2  1  1  1  1
# 3  1  1  1  1

v <- c('X2', 'X4')  ## create vector of column names (or numbers) to change

df[v] <- df[v] - 1  ## subtract and assign back

df  ## result
#   X1 X2 X3 X4
# 1  1  0  1  0
# 2  1  0  1  0
# 3  1  0  1  0

Data:

df <- data.frame(matrix(1, 3, 4))
jay.sf
  • 60,139
  • 8
  • 53
  • 110