0

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.

Corbjn
  • 276
  • 1
  • 10
  • Can you add part of your data using `dput(head(nr))` so that we know what kind of data we are dealing with? – Ronak Shah Aug 17 '20 at 00:05

4 Answers4

1

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.

Eric
  • 2,699
  • 5
  • 17
  • Yes and that's the step where everything gets overwritten with zeros. – Corbjn Aug 16 '20 at 19:33
  • Try using two lines of code with separate assignments like in my example. The sequencing going on within your single line of code with two assignments is causing it to result to 0. – Eric Aug 16 '20 at 20:02
  • Yes. I expect this as a result. But when I do `nr[!is.finite(nr)] <- 0` everything in the vector gets overwritten with zeros. No matter if I execute your two lines or my version in one line. `nr` is kind of a numeric version of the raster object you get with `getValues()`. If i do `str(nr)` I get: `num [1:120560400] 0.357 0.379 0.376 0.372 0.413 ...`. – Corbjn Aug 16 '20 at 20:03
  • 2
    It may be that your raster is too large. Perhaps [this](https://gis.stackexchange.com/questions/278319/replace-nas-with-0-for-large-raster-data-using-r) can help provide a solution? – Eric Aug 16 '20 at 20:07
  • 1
    `d = reclassify(r, cbind(NA, NA, 0), right=FALSE)` where `r` is the raster does it. Thank you for your help! – Corbjn Aug 17 '20 at 08:34
  • @Corbjn You are welcome. I have updated my solution. You may want to mark it complete by clicking the checkmark which would make it easier to find a solution for people who may be dealing with the same thing in the future. Also, it would be best to edit your question to include the contents of `nr`. – Eric Aug 17 '20 at 08:55
0

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.

Josh Purtell
  • 334
  • 2
  • 10
  • str(nr) gets: `num [1:120560400] 0.357 0.379 0.376 0.372 0.413 ...` nr is the raster object as numeric. You get it with getValues(). – Corbjn Aug 16 '20 at 19:59
0

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

David J. Bosak
  • 1,386
  • 12
  • 22
0

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
Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63