1

How can I loop through a dataframe and check for Inf and NA values in each cell. If there is an Inf or NA value in the cell then change it to a value of 0.

Here is an example dataframe

testdf <- data.frame(b1 = c(1,Inf,5,7,8,9,200,736, Inf, Inf), 
b2 = c(2,3,Inf, NA,4,78,23,567,9114,94), 
b3 = c(23,45,86,1236,78,Inf,324,2100,49,10))

> testdf
    b1   b2   b3
1    1    2   23
2  Inf    3   45
3    5  Inf   86
4    7   NA 1236
5    8    4   78
6    9   78  Inf
7  200   23  324
8  736  567 2100
9  Inf 9114   49
10 Inf   94   10

unmanned15
  • 227
  • 1
  • 3
  • 19
  • You can use `testdf[sapply(testdf, is.infinite) | is.na(testdf)] <- 0`. Except perhaps for the fact that there isn't a data.frame method for `is.infinite()` this is a common dupe. – Ritchie Sacramento Aug 05 '19 at 00:46
  • I warn against arbitrarily converting an `NA` to `0`, as that changes the *meaning* of the data. For instance, `NA` means something like *"I do not have data"* or *"this is not applicable"*, whereas finding a 0 means *"there is data for this cell and it is zero"*. This is obviously contextual, but rarely do I convert non-numbers to a number, whether that be 0, 1, or something else. (The act of *imputing* is necessary sometimes, granted.) – r2evans Aug 05 '19 at 00:54

1 Answers1

2

Here's a way using lapply from base R -

testdf[] <- lapply(testdf, function(x) {
  replace(x, is.na(x) | is.infinite(x), 0)
})

    b1   b2   b3
1    1    2   23
2    0    3   45
3    5    0   86
4    7    0 1236
5    8    4   78
6    9   78    0
7  200   23  324
8  736  567 2100
9    0 9114   49
10   0   94   10

Thanks to @thelatemail, a simplified version considering that !is.finite(c(Inf,NA)) returns TRUE for both -

testdf[] <- lapply(testdf, function(x) replace(x, !is.finite(x), 0))

Anther way using solution from @H1 comment -

testdf[sapply(testdf, Negate(is.finite))] <- 0
Shree
  • 10,835
  • 1
  • 14
  • 36
  • 2
    `!is.finite(c(Inf,NA))` returns 2 `TRUE`s so you could use it alone - `testdf[] <- lapply(testdf, function(x) replace(x, !is.finite(x), 0))` I think. – thelatemail Aug 05 '19 at 02:10