Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

change all negative values in a column of a data frame to zero

Tags:

r

In R, how can I change all negative values in a column of a data frame to zero? Is there a simple function that can be used together with apply() to do this job? Alternatively, how to write a loop to do it? Thank you very much!

like image 299
Runner Avatar asked Jun 04 '14 20:06

Runner


People also ask

How do you change a negative number to 0 in R?

Data Visualization using R Programming To convert negative values in a matrix to 0, we can use pmax function. For example, if we have a matrix called M that contains some negative and some positive and zero values then the negative values in M can be converted to 0 by using the command pmax(M,0).


3 Answers

You can use an ifelse command:

df$column <- ifelse(df$column < 0, 0, df$column)

or as @Jilber said in the comments:

df$column[df$column < 0] <- 0

or

within(df, column[column<0] <- 0)
like image 104
Jaap Avatar answered Nov 02 '22 18:11

Jaap


Probably easier to use the ifelse statement that @Jaap suggested or the indexing that was suggested as well, but I find this method to be fun (taking advantage of boolean algebra)

> dat<-data.frame(c1=sample(c(10,-10),10,T))
> dat
    c1
1  -10
2   10
3  -10
4   10
5   10
6   10
7  -10
8   10
9   10
10 -10
> dat<-within(dat, c1<-c1*(c1>0))
> dat
   c1
1   0
2  10
3   0
4  10
5  10
6  10
7   0
8  10
9  10
10  0

It can also provide some performance gains over ifelse/indexing in this situation (naturally, this is much less flexible, so perhaps the performance gains aren't worth it in all cases)

> dat<-data.frame(c1=sample(c(10,-10),1e6,T))
> system.time(within(dat, c1<-ifelse(c1 < 0, 0, c1)))
   user  system elapsed
  0.382   0.000   0.386
> system.time(dat[dat$c1 < 0,] <- 0)
   user  system elapsed
   0.08    0.00    0.08
> system.time(within(dat, c1<-c1*(c1>0)))
   user  system elapsed
  0.043   0.000   0.044
> dat1<-within(dat, c1<-ifelse(c1 < 0, 0, c1))
> dat2<-within(dat, c1<-c1*(c1>0))
> identical(dat1,dat2)
[1] TRUE
like image 39
JPC Avatar answered Nov 02 '22 18:11

JPC


Using dplyr:

library(dplyr)

> df <- tibble(c1 = sample(c(10, -10), 10, T))
> df
# A tibble: 10 x 1
      c1
   <dbl>
 1    10
 2   -10
 3    10
 4   -10
 5   -10
 6    10
 7    10
 8   -10
 9   -10
10    10

> df %>% mutate(c1 = if_else(c1 < 0, 0, c1))
# A tibble: 10 x 1
      c1
   <dbl>
 1    10
 2     0
 3    10
 4     0
 5     0
 6    10
 7    10
 8     0
 9     0
10    10
like image 20
Werner Avatar answered Nov 02 '22 19:11

Werner