3

I have a data frame like this:

Input_df <- data.frame(Enl_ID = c("INTS121410", "INTS175899", "INTS171428", "INTS156006", "INTS196136", "INTS114771" ), `CN4244` = c(5, 0, -0.4, -0.6, 10, 2), `CN4249` = c(10, -4, -10, -2, 6, 0), `CN4250` = c(40, 10, 4, -10, 0, 4))

I'm trying to rescale the positive values between 0-1 and negative values between 0 to -1 so the output would be like

Output_df <- data.frame(Enl_ID = c("INTS121410", "INTS175899", "INTS171428", "INTS156006", "INTS196136", "INTS114771" ), `CN4244` = c(0.5, 0, -0.66, -1, 1, 0.2), `CN4249` = c(1, -0.4, -1, -0.2, 0.6, 0), `CN4250` = c(1, 0.25, 0.1, -1, 0, 0.1))

I found few examples like at stackoverflow but this is only for single-column and my file run into almost 2000 column so it is not possible to do it manually on every column.

Any idea how to do it?

Any help would be appreciated. Thanks in advance

Martin Gal
  • 16,640
  • 5
  • 21
  • 39
SUMIT
  • 563
  • 4
  • 12

1 Answers1

4

You could use

library(dplyr)

Input_df %>% 
  mutate(across(starts_with("CN"), ~.x / max(abs(.x))))

This returns

      Enl_ID CN4244 CN4249 CN4250
1 INTS121410   0.50    1.0   1.00
2 INTS175899   0.00   -0.4   0.25
3 INTS171428  -0.04   -1.0   0.10
4 INTS156006  -0.06   -0.2  -0.25
5 INTS196136   1.00    0.6   0.00
6 INTS114771   0.20    0.0   0.10

Or, if you want different rescaling factors for positive and negative values:

Input_df %>% 
  mutate(across(starts_with("CN"), 
                ~case_when(.x >= 0 ~ .x / max(.x), 
                           TRUE ~ - .x / min(.x))))

This returns

      Enl_ID     CN4244 CN4249 CN4250
1 INTS121410  0.5000000    1.0   1.00
2 INTS175899  0.0000000   -0.4   0.25
3 INTS171428 -0.6666667   -1.0   0.10
4 INTS156006 -1.0000000   -0.2  -1.00
5 INTS196136  1.0000000    0.6   0.00
6 INTS114771  0.2000000    0.0   0.10
Martin Gal
  • 16,640
  • 5
  • 21
  • 39