Vectorized (non-loop) solution returns wrong result (solution with for-loop returns correct result)

StackOverflow https://stackoverflow.com/questions/23636212

  •  21-07-2023
  •  | 
  •  

문제

I have theoretically identical solutions, one is vectorized solution and another is with for-loop. But vectorized solution returns wrong result and I want to understand why. Solution's logic is simple: need to replace NA with previous non-NA value in the vector.

# vectorized
f1 <- function(x) {
    idx <- which(is.na(x))
    x[idx] <- x[ifelse(idx > 1, idx - 1, 1)]
    x
}

# non-vectorized
f2 <- function(x) {
    for (i in 2:length(x)) {
        if (is.na(x[i]) && !is.na(x[i - 1])) {
            x[i] <- x[i - 1]
        }
    }
    x
}

v <- c(NA,NA,1,2,3,NA,NA,6,7)
f1(v)
# [1] NA NA  1  2  3  3 NA  6  7
f2(v)
# [1] NA NA  1  2  3  3  3  6  7
도움이 되었습니까?

해결책

The two pieces of code are different.

  • The first one replace NA with the previous element if this one is not NA.
  • The second one replace NA with the previous element if this one is not NA, but the previous element can be the result of a previous NA substitution.

Which one is correct really depends on you. The second behaviour is more difficult to vectorize, but there are some already implemented functions like zoo::na.locf.

Or, if you only want to use base packages, you could have a look at this answer.

다른 팁

These two solutions are not equivalent. The first function is rather like:

f2_as_f1 <- function(x) {
    y <- x # a copy of x
    for (i in 2:length(x)) {
        if (is.na(y[i])) {
            x[i] <- y[i - 1]
        }
    }
    x
}

Note the usage of the y vector.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top