Remove NA/NaN/Inf in a matrix
Asked Answered
M

4

19

I want to try two things :

  1. How do I remove rows that contain NA/NaN/Inf
  2. How do I set value of data point from NA/NaN/Inf to 0.

So far, I have tried using the following for NA values, but been getting warnings.

> eg <- data[rowSums(is.na(data)) == 0,]
 Error in rowSums(is.na(data)) : 
       'x' must be an array of at least two dimensions
     In addition: Warning message:
     In is.na(data) : is.na() applied to non-(list or vector) of type 'closure'
Muddy answered 2/4, 2013 at 19:55 Comment(2)
The warning is because you haven't defined data, which is also a function in the utils package. I.e., you were calling is.na on a function, which doesn't make sense.Hallette
Related post: #7518745Howling
H
42

I guess I'll throw my hat into the ring with my preferred methods:

# sample data
m <- matrix(c(1,2,NA,NaN,1,Inf,-1,1,9,3),5)
# remove all rows with non-finite values
m[!rowSums(!is.finite(m)),]
# replace all non-finite values with 0
m[!is.finite(m)] <- 0
Hallette answered 2/4, 2013 at 20:17 Comment(2)
How would you remove columns with some NA? 'm[!colSums(!is.finite(m)),]' does not workFrumentaceous
@vog: you're subsetting m by rows. You need m[, !colSums(!is.finite(m))] for columns.Hallette
L
13
library(functional)
m[apply(m, 1, Compose(is.finite, all)),]

Demonstration:

m <- matrix(c(1,2,3,NA,4,5), 3)
m
##      [,1] [,2]
## [1,]    1   NA
## [2,]    2    4
## [3,]    3    5

m[apply(m, 1, Compose(is.finite, all)),]
##      [,1] [,2]
## [1,]    2    4
## [2,]    3    5

Note: Compose(is.finite, all) is equivalent to function(x) all(is.finite(x))

To set the values to 0, use matrix indexing:

m[!is.finite(m)] <- 0
m
##      [,1] [,2]
## [1,]    1    0
## [2,]    2    4
## [3,]    3    5
Lowrey answered 2/4, 2013 at 20:0 Comment(4)
Oh, sorry, missed the Inf.Lowrey
But what about second part of my ques? Setting them all to zero and not remove them at all?Muddy
You use the fact that is.finite(m) returns a logical matrix.Lowrey
Suggestion: use m[apply(m, 1, Compose(is.finite, all)), , drop=FALSE] to avoid losing dimensions.Kristopherkristos
A
9

NaRV.omit(x) is my preferred option for question 1. Mnemonic NaRV means "not a regular value".

require(IDPmisc)
m <- matrix(c(1,2,3,NA,5, NaN, 7, 8, 9, Inf, 11, 12, -Inf, 14, 15), 5)
> m
     [,1] [,2] [,3]
[1,]    1  NaN   11
[2,]    2    7   12
[3,]    3    8 -Inf
[4,]   NA    9   14
[5,]    5  Inf   15
> NaRV.omit(m)
     [,1] [,2] [,3]
[1,]    2    7   12
attr(,"na.action")
[1] 1 3 4 5
attr(,"class")
[1] "omit"
Adolescent answered 20/10, 2014 at 15:2 Comment(1)
great package! exactly what I need!Xenia
J
4

Just another way (for the first question):

m <- structure(c(1, 2, 3, NA, 4, 5, Inf, 5, 6, NaN, 7, 8), 
              .Dim = c(4L, 3L))
#      [,1] [,2] [,3]
# [1,]    1    4    6
# [2,]    2    5  NaN
# [3,]    3  Inf    7
# [4,]   NA    5    8

m[complete.cases(m * 0), , drop=FALSE]
#      [,1] [,2] [,3]
# [1,]    1    4    6

I can't think anything else other than Matthew's answer for the second part.

Joggle answered 2/4, 2013 at 20:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.