0

I have an R dataframe like below with all numeric columns. All non NA values are either greater than/equal to 1 or less than -1. I want to subtract 1 from all the positive values and add 1 to all the negative values, ignoring all the NAs.

Input dataframe

My output dataframe should look like below

Output dataframe

I know how to replace NAs with zero and vice versa

df[is.na(df)] <- 0
df[df==0] <- NA

I tried something similar for my problem also

df[df >= 1] <- df - 1
df[df < -1] <- df + 1

Getting an error 'value' is the wrong length. Also tried ifelse

df <- ifelse(df >= 1, df - 1, df + 1)

This is subtracting 1 from all values (including negatives). Also tried if and else separately

if(df >= 1){
   df <- df - 1
}else if(df < -1){
   df <- df + 1
}

This is also subtracting 1 from all. I have programmed in other languages before and relatively new to R. Need help on this. My actual dataframe is having more than 1000 columns.

I found a similar question on stackoverflow, but the answers are using specific column indexes which is not possible in my case.

penguin
  • 1,267
  • 14
  • 27

2 Answers2

1

You can try

sapply(df, function(x) ifelse(x >= 1, x - 1, x + 1))
#     col1 col2 col3
#[1,] -0.4  1.1   NA
#[2,]  0.2 -1.0  0.5
#[3,]   NA   NA  0.0

data

df <- data.frame(col1 = c(-1.4, 1.2, NA), col2 = c(2.1, -2, NA), col3 = c(NA, 1.5, 1))
markus
  • 25,843
  • 5
  • 39
  • 58
1

alternately using tidyverse functions, you can try:

df %>%
  mutate_all(funs(if_else( .>1, . -1, . +1)))

which gives:

  col1 col2 col3
1 -0.4  1.1   NA
2  0.2 -1.0  0.5
3   NA   NA  2.0
Aramis7d
  • 2,444
  • 19
  • 25
  • It is very slow on my dataset. Plus it requires an extra package. sapply(df, function(x) ifelse(x >= 1, x - 1, x + 1)) as mentioned in other answer seems like better option. Thanks – penguin Feb 16 '18 at 12:57