12

I have a dataframe. I'd like to subtract the 2nd column from all other columns. I can do it in a loop, but I'd like to do it in one call. Here's my working loop code:

df <- data.frame(x = 100:101, y = 2:3,z=3:4,a = -1:0,b=4:5)

for( i in 3:length(df) ) {
    df[i] <- df[i] - df[2]
}
TPM
  • 775
  • 3
  • 8
  • 20

3 Answers3

11

If you need to subtract the columns 3:ncol(df) from the second column

df[3:ncol(df)] <- df[3:ncol(df)]-df[,2]
akrun
  • 789,025
  • 32
  • 460
  • 575
  • Perfect. Thank you. I tried that, but didn't have the comma before the 2 so got an error saying the dataframes didn't match. – TPM Mar 04 '15 at 15:38
  • 1
    @TPM The `df[2]` is still a dataframe and the dimensions won't be matching with the other dataset, while `df[,2]` is a vector and it will do the subtraction for each column of `df[3:ncol(df)]` by recycling – akrun Mar 04 '15 at 15:41
3

Another solution using dplyr::mutate_at() function

# install.packages("dplyr", dependencies = TRUE)
library(dplyr)

df <- data.frame(x = 100:101, y = 2:3, z = 3:4, a = -1:0, b = 4:5)
df %>%
  mutate_at(vars(-matches("y"), -matches("x")), list(dif = ~ . - y))
#>     x y z  a b z_dif a_dif b_dif
#> 1 100 2 3 -1 4     1    -3     2
#> 2 101 3 4  0 5     1    -3     2

Created on 2019-11-05 by the reprex package (v0.3.0)

Tung
  • 23,290
  • 6
  • 81
  • 97
  • Related https://stackoverflow.com/questions/48898121/mutate-multiple-variable-to-create-multiple-new-variables/ – Tung Nov 05 '19 at 14:16
0

This would also work - returns the 9 columns that you subtracted the second one from.

 df = data.frame(matrix(rnorm(100,0,1),nrow = 10))
 df[,-2] - df[,2]
Michael Discenza
  • 3,062
  • 6
  • 29
  • 41
  • 2
    The OP wants to subtract only from `3:ncol(df)` , you may need `df[-c(1:2)]` Having said that, this is basically the approach used by the solution I posted – akrun Mar 04 '15 at 15:45
  • @akrun, good catch, you're right. You would need that to get the same result as the code provided above – Michael Discenza Mar 04 '15 at 15:51