Sam Gilbert
Sam Gilbert

Reputation: 1702

Convert negative values to zero in dataframe in R

I have a dataframe in R that I would like to convert all columns (outside the ids) from negative to zero

id1  id2  var1  var2  var3
-1   -1   0     -33     5
-1   -2   9     -10    -1

I can convert all columns with code line like:

temp[temp < 0] <- 0

But I can't adjust it to only a subset of columns. I've tried:

temp[temp < 0, -c(1,2)] <- 0

But this errors saying non-existent rows not allowed

Upvotes: 12

Views: 22132

Answers (5)

akrun
akrun

Reputation: 887088

We can use data.table

setDT(d1)
for(j in grep('^var', names(d1))){
 set(d1, i= which(d1[[j]]<0), j= j, value=0)
}

d1
#    id1 id2 var1 var2 var3
# 1:  -1  -1    0    0    5
# 2:  -1  -2    9    0    0

Upvotes: 2

Ken Benoit
Ken Benoit

Reputation: 14902

There might be fancier or more compact ways, but here's a vectorised replacement you can apply to the var columns:

mytable <- read.table(textConnection("
id1  id2  var1  var2  var3
-1   -1   0     -33     5
-1   -2   9     -10    -1"), header = TRUE)

mytable[, grep("^var", names(mytable))] <- 
    apply(mytable[, grep("^var", names(mytable))], 2, function(x) ifelse(x < 0, 0, x))
mytable
##    id1 id2 var1 var2 var3
##  1  -1  -1    0    0    5
##  2  -1  -2    9    0    0

Upvotes: 1

Karsten W.
Karsten W.

Reputation: 18420

You could use pmax:

dat <- data.frame(id1=c(-1,-1), id2=c(-1,-2), var1=c(0,9), var2=c(-33,10), var3=c(5,-1))
dat[,-c(1,2)] <- matrix(pmax(unlist(dat[,-c(1,2)]),0), nrow=nrow(dat))

Upvotes: 0

Batanichek
Batanichek

Reputation: 7871

Edit a bit your variant

temp[,-c(1,2)][temp[, -c(1,2)] < 0] <- 0

Upvotes: 14

A5C1D2H2I1M1N2O1R2T1
A5C1D2H2I1M1N2O1R2T1

Reputation: 193517

You can try using replace:

> mydf[-c(1, 2)] <- replace(mydf[-c(1, 2)], mydf[-c(1, 2)] < 0, 0)
> mydf
  id1 id2 var1 var2 var3
1  -1  -1    0    0    5
2  -1  -2    9    0    0

Upvotes: 7

Related Questions