25

I have a simple issue, but I couldn't grasp the logic to overcome it.

I have numeric vectors with NAs and want to apply a condition-dependent operation on them.

A simple example similar to my problem is:

x <- c(1,3,5,7,NA,2,4,6)
x[x>=5] <- c(1:8)[x>=5]
x[x<5] <- (c(1:8)*10)[x<5]

It returns the error "NAs are not allowed in subscripted assignments", so I'd like to know what would be a sensible solution for that, given that running each attribution separately works as expected.

I would like to have the expected result of:

[1]  10  20  3  4 NA  60  70  8

Preferably without having to make a for loop, as this operation is already in a function for null modelling with lots of iterations that is taking ages.

Thank you in advance, Leonardo

NB. NAs mean Not Available values

LeoRJorge
  • 474
  • 1
  • 5
  • 13
  • 5
    This is very interesting. It seems that you can't combine integers with `NA` while subsetting and assigning only if you have more than one value on RHS... I.e. `x[c(NA, 1)] <- 100` and `x[NA] <- 100` will both work, while `x[c(NA, 1)] <- 100:101` or `x[NA] <- 100:101` won't – David Arenburg Nov 12 '14 at 17:59
  • 2
    This is a valuable question as it gets at that error message. But it's important to note that even if your code ran without the NA-caused errors, it wouldn't produce that expected result. Line 2 of your code would overwrite the original values of 5 and 7 that you used to predict the result of 3 and 4 above (instead of 30 and 40), and they would be 3 and 4 by the time line 3 is called, causing them to become 30 and 40. Try: `x[x>=5 & !is.na(x)] <- c(1:8)[x>=5 & !is.na(x)] ; x[x<5 & !is.na(x)] <- (c(1:8)*10)[x<5 & !is.na(x)]` – Sam Firke Oct 13 '15 at 19:50

3 Answers3

20

Your logic will need to also exclude NAs in the subset. See the following example. Note the subsets vectors are stored away before x is modified.

x <- c(1,3,5,7,NA,2,4,6)
subset1 <- x>=5 & !is.na(x)
subset2 <-  x<5 & !is.na(x)

x[subset1] <- which(subset1)
x[subset2] <- 10*which(subset2)
vpipkt
  • 1,710
  • 14
  • 17
0

I think you are intermixing assignment and subscripting. I believe what you are after is something closer to this:

x <- c(1,3,5,7,NA,2,4,6)
x.greater <- c(1:8)[x>=5]
x.less <- (c(1:8)*10)[x<5]

x.greater
# 3  4 NA  8
x.less
# 10 20 NA 60 70

result <- c(x.greater, x.less)
result
# 3  4 NA  8 10 20 NA 60 70
JasonAizkalns
  • 20,243
  • 8
  • 57
  • 116
0
x <- c(1,3,5,7,NA,2,4,6)

x.greater <- c(1:8)*(x>=5)
# 0  0  3  4 NA  0  0  8

x.less <- c(1:8)*10*(x<5)
# 10 20  0  0 NA 60 70  0

result <- x.greater + x.less
# 10 20  3  4 NA 60 70  8
萩nao
  • 1