How to replace variables with NEGATIVE values with ZERO within a date.frame in R?

Asked

Viewed 909 times

3

Let’s say I have a 6x5 data.frame, for example:

print(Dados)

Linha  A   B   C   D   E
L1     4   3  -1   2   4
L2     1  -2   1  -5   1
L3    -1  -1   2   3   4
L4     2   4   5  -7   9

But I want to replace the Negative values of the data.frame with Zeros, for example:

Linha  A   B   C   D   E
L1     4   3   0   2   4
L2     1   0   1   0   1
L3     0   0   2   3   4
L4     2   4   5   0   9

How can I replace variables with NEGATIVE values by ZERO within my date frame.?

Dice.

Dados <- read.table(text = "
Linha  A   B   C   D   E
L1     4   3  -1   2   4
L2     1  -2   1  -5   1
L3    -1  -1   2   3   4
L4     2   4   5  -7   9
", header = TRUE)
  • 2

    Why close? This question is about programming and may even have answers only in R base or with the package dplyr.

  • 1

    If you don’t care about Warning the simplest way q exists is Dados[Dados<0] <- 0it will replace anything negative with 0 will happen a Warning pq your data.framenot all in numbers, strings in the middle ...

  • Thanks for the support @Rui Barradas

2 answers

2

With only R base it is possible to do this.

I will present two solutions using ifelse:

data_1 <- sapply(X = Dados[c(2:6)], FUN = function(x) {
  ifelse(test = x < 0, 0, x)
})

data_1

     A B C D E
[1,] 4 3 0 2 4
[2,] 1 0 1 0 1
[3,] 0 0 2 3 4
[4,] 2 4 5 0 9

Note that in this case you need to know the indices of the vectors within the data.frame. I mean, you have to do this: X = Dados[c(2:6)].

But suppose you want to replace with zeros only for variables that have a certain class, like integer (integer vector). With rapply you do that:

data_2 <- rapply(object = Dados, classes = 'integer', how = 'replace', f = function(x) {
  ifelse(test = x < 0, 0, x)
})

data_2

  Linha A B C D E
1    L1 4 3 0 2 4
2    L2 1 0 1 0 1
3    L3 0 0 2 3 4
4    L4 2 4 5 0 9

A simpler solution, if you know that the first variable is not numerical, is this:

Dados[-1][Dados[-1] < 0] <- 0
Dados

  Linha A B C D E
1    L1 4 3 0 2 4
2    L2 1 0 1 0 1
3    L3 0 0 2 3 4
4    L4 2 4 5 0 9
  • 1

    Thanks for the answer, I’ll test.

  • 2

    -c(1) and -1 are the same vector, the second form is simpler.

2


Here’s another way, with the package dplyr. Utilizes the mutate_if (mutate conditional) to determine which columns are numerical and modifies only those columns. The function neg2zero serves to make the code more readable.

library(dplyr)

neg2zero <- function(x) {
  x[x < 0] <- 0
  x
}

Dados %>%
  mutate_if(is.numeric, neg2zero)
#  Linha A B C D E
#1    L1 4 3 0 2 4
#2    L2 1 0 1 0 1
#3    L3 0 0 2 3 4
#4    L4 2 4 5 0 9

Now that the main idea is shown, you can use an anonymous function.

Dados %>%
  mutate_if(is.numeric, function(x) {x[x < 0] <- 0; x})
#  Linha A B C D E
#1    L1 4 3 0 2 4
#2    L2 1 0 1 0 1
#3    L3 0 0 2 3 4
#4    L4 2 4 5 0 9

Browser other questions tagged

You are not signed in. Login or sign up in order to post.