Assume that we have a data frame in which every column is numeric. For example assume the data frame, BOD2, defined in the Note at the end based on the BOD data frame that comes with R.
1) lapply Then for each column perform the operation creating a list of columns and convert it back into a data frame. We can replace the indicated function with any other function as long as it represents an operation which is vectorized in R.
No packages are used.
as.data.frame(lapply(BOD2, function(x) ifelse(x > 0, x, -x/2)))
giving:
Time demand
1 0.5 8.3
2 0.5 10.3
3 3.0 19.0
4 4.0 16.0
5 5.0 15.6
6 7.0 19.8
If there are non-numeric columns then use:
as.data.frame(lapply(BOD2, function(x) {
if (is.numeric(x)) ifelse(x > 0, x, -x/2) else x
}))
2) pmax Alternately for this particular transformation we can use pmax giving the same result.
pmax(BOD2, -BOD2/2)
or if there are non-numeric columns then
is_num <- sapply(BOD2, is.numeric)
BOD3 <- BOD2[is_num]
replace(BOD2, is_num, pmax(BOD3, -BOD3/2))
3) dplyr Using dplyr we can do this:
library(dplyr)
BOD2 %>% mutate(across(where(is.numeric), ~ ifelse(. > 0, ., -./2)))
4) collapse We can use ftransformv from the collapse package:
library(collapse)
ftransformv(BOD2, is.numeric, function(x) ifelse(x > 0, x, -x/2))
Note
BOD2 <- BOD
BOD2[1:2, 1] <- -1
so BOD2 looks like this:
Time demand
1 -1 8.3
2 -1 10.3
3 3 19.0
4 4 16.0
5 5 15.6