Home > Enterprise >  Replace selected columns' negative values with 0s or NAs using R
Replace selected columns' negative values with 0s or NAs using R

Time:04-18

For the example data df, I want to replace the negative values in the first column (x1) with 0 and the third column (x3) with NA by the function replace_negatives as follows:

df  <- data.frame(x1 = -3:1,      
                    x2 = -1,
                    x3 = -2:2)
df 

Out:

  x1 x2 x3
1 -3 -1 -2
2 -2 -1 -1
3 -1 -1  0
4  0 -1  1
5  1 -1  2

Please note that I do not index by column names because there are many columns in the actual data and the column names are not fixed.

replace_negatives <- function(data){
  df <<- data %>% 
    mutate(.[[1]] = if_else(.[[2]] < 0, 0, .[[1]])) %>%
    mutate(.[[3]] = if_else(.[[3]] < 0, NA, .[[3]])) 
  return(df)
}

lapply(df, replace_negatives)

But it raises an error:

> replace_negatives <- function(data){
    df <<- data %>% 
      mutate(.[[1]] = if_else(.[[2]] < 0, 0, .[[1]])) %>%
Error: unexpected '=' in:
"  df <<- data %>% 
    mutate(.[[1]] ="
>     mutate(.[[3]] = if_else(.[[3]] < 0, NA, .[[3]])) 
Error: unexpected '=' in "    mutate(.[[3]] ="
>   return(df)
Error: no function to return from, jumping to top level
> }
Error: unexpected '}' in "}"

Any helps would be appriciated.

The expected output:

  x1 x2 x3
1  0 -1 NA
2  0 -1 NA
3  0 -1  0
4  0 -1  1
5  1 -1  2

CodePudding user response:

You could use across in the function:

library(tidyverse)

replace_negatives <- function(data){
  df <- data %>%
    mutate(across(1, ~ ifelse(. < 0, 0, .)),
           across(3, ~ ifelse(. < 0, NA, .)))
  return(df)
}

replace_negatives(df)

Output

  x1 x2 x3
1  0 -1 NA
2  0 -1 NA
3  0 -1  0
4  0 -1  1
5  1 -1  2

CodePudding user response:

To perform the required operation, here's a base R method:

df  <- data.frame(x1 = -3:1,      
                  x2 = -1,
                  x3 = -2:2)

df[[1]] <- ifelse(df[[1]] < 0, 0, df[[1]])
df[[3]] <- ifelse(df[[3]] < 0, NA, df[[3]])

df
#>   x1 x2 x3
#> 1  0 -1 NA
#> 2  0 -1 NA
#> 3  0 -1  0
#> 4  0 -1  1
#> 5  1 -1  2

Created on 2022-04-18 by the reprex package (v2.0.1)

CodePudding user response:

Here is base R version of your function:

replace_negatives <- function(df){
    is.na(df[,1]) <- df[,1] < 0
    index <- df[,3] < 0
    df[,3][index] <- 0
  return(df)
}


replace_negatives(df)
  x1 x2 x3
1 NA -1  0
2 NA -1  0
3 NA -1  0
4  0 -1  1
5  1 -1  2
  • Related