Paolo Veronesi
Paolo Veronesi

Reputation: 1

How to substitute negative values with a calculated value in an entire dataframe

I've got a huge dataframe with many negative values in different columns that should be equal to their original value*0.5. I've tried to apply many R functions but it seems I can't find a single function to work for the entire dataframe. I would like something like the following (not working) piece of code:

mydf[] <- replace(mydf[], mydf[] < 0, mydf[]*0.5)

Upvotes: 0

Views: 155

Answers (3)

Sotos
Sotos

Reputation: 51622

You can simply do,

mydf[mydf<0] <- mydf[mydf<0] * 0.5

If you have values that are non-numeric, then you may want to apply this to only the numeric ones,

ind <- sapply(mydf, is.numeric)
mydf1 <- mydf[ind]
mydf1[mydf1<0] <- mydf1[mydf1<0] * 0.5
mydf[ind] <- mydf1

Upvotes: 6

akrun
akrun

Reputation: 887981

In the replace the values argument should be of the same length as the number of TRUE values in the list ('index' vector)

replace(mydf, mydf <0, mydf[mydf <0]*0.5)

Or another option is set from data.table, which would be very efficient

library(data.table)
for(j in seq_along(mydf)){
  i1 <- mydf[[j]] < 0
  set(mydf, i = which(i1), j= j, value = mydf[[j]][i1]*0.5)
 }

data

set.seed(24)
mydf <- as.data.frame(matrix(rnorm(25), 5, 5))

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 522787

You could try using lapply() on the entire data frame, making the replacements on each column in succession.

df <- lapply(df, function(x) {
    x <- ifelse(x < 0, x*0.5, x)
})

The lapply(), or list apply, function is intended to be used on lists, but data frames are a special type of list so this works here.

Demo

Upvotes: 1

Related Questions