Corbjn
Corbjn

Reputation: 286

R: Can't replace NAs with zeros in vector

I know that topic arose plenty of times in the past as it is found multiple times via google search. But somehow I can't replace NAs in a vector with zeros, instead all values get overwritten.

I wanted to do some kmeans clustering following this guide. As I proceeded to the step where I have to use the setValues() function, I recognized that the length between both inputs differs. I thought that the reason for that are some NA Values, so I checked if there are NAs and if true, to overwrite them with zeros.

To check I did:

sum(is.infinite(nr))
sum(is.na(nr))
sum(is.nan(nr))

After that I knew that there are some NAs. So I followed this SO. After typing:

nr_2 <- nr[!is.finite(nr)] <- 0

All values got overwritten with zeros. So I checked the data type of nr. RStudio stated 'Large Numeric' and after typing is.vector(nr) it returned TRUE. Did I something wrong with indexing? So I tried to extract a single value with nr[1] and I got what I expected. But I also tried nr[[1]] and it worked also and returned the same value. And at that point some explanation would be great.

But the main question remians, why I can't replace NAs with zeros.

Upvotes: 0

Views: 224

Answers (4)

Eric
Eric

Reputation: 2849

It looks like nr is assigned the value of 0, then nr_2 is assigned the value of nr.

Are you expecting an outcome like the one provided below? If so, try breaking your code out into two separate assignments. Here I am using a numeric vector:

nr <- c(0, 4, 21, 10, 68, NA, NaN, Inf, -Inf, 10, 20, NA, NA, 9, 10)

nr[!is.finite(nr)] <- 0
nr_2 <- nr
nr_2
#>  [1]  0  4 21 10 68  0  0  0  0 10 20  0  0  9 10

Created on 2020-08-16 by the reprex package (v0.3.0)

Since you pointed out that this is a rather large raster object:

str(nr) I get: num [1:120560400] 0.357 0.379 0.376 0.372 0.413 ...

consider using the following:

nr_2 = reclassify(nr, cbind(NA, NA, 0), right=FALSE)

And referencing this for additional information.

Upvotes: 1

Robert Hijmans
Robert Hijmans

Reputation: 47036

Given that you are dealing with a raster object, presumably a RasterLayer

library(raster)
r  <- raster(nrow=10, ncol=10, values=1:100)
r[1:10] = NA

Now you can do (my preference)

d <- reclassify(r, cbind(NA, 0))

Or the below approaches (which are meant for quick interactive operations on smaller objects)

r[is.na(r)] <- 0

Or

r[!is.finite(r)] <- 0

Upvotes: 0

David J. Bosak
David J. Bosak

Reputation: 1624

Both Josh and Eric correctly pointed out that the problem is with the assignment to nr_2, not the assignment of zeroes to nr. But I wanted to mention that you can also do this with an ifelse() function, if that helps you make more sense of it. Like so:

nr <- c(0, 4, 21, 10, 68, NA, NaN, Inf, -Inf, 10, 20, NA, NA, 9, 10)
nr_2 <- ifelse(is.finite(nr), nr, 0)
nr_2

# [1]  0  4 21 10 68  0  0  0  0 10 20  0  0  9 10

Upvotes: 0

Josh Purtell
Josh Purtell

Reputation: 364

I don't have enough reputation to comment, but @Corbjn could you expound upon exactly what constitutes nr? Printing str(nr) might be sufficient. As @Eric elaborated

small_vec<-c(NA,1,NA,1)
small_vec[is.na(small_vec)]<-0
#> num [1:4] 0 1 0 1

demonstrates a reprex of the desired operation for numeric vectors https://stat.ethz.ch/R-manual/R-devel/library/base/html/numeric.html.

Upvotes: 0

Related Questions