r 自定义函数中的局部变量问题

Issue with local variables in r custom function

我有一个数据集

>view(interval)
#   V1 V2 V3 ID
# 1 NA 1  2  1
# 2 2  2  3  2
# 3 3  NA 1  3
# 4 4  2  2  4
# 5 NA 5  1  5

>dput(interval)
structure(list(V1 = c(NA, 2, 3, 4, NA),
V2 = c(1, 2, NA, 2, 5),
V3 = c(2, 3, 1, 2, 1), ID = 1:5), row.names = c(NA, -5L), class = "data.frame")

我想为每一行提取前一个非 NA 值(或下一个,如果 NA 在第一行),并将其作为局部变量存储在自定义函数中,因为我必须执行其他操作基于此值对每一行进行操作(我正在应用该函数的每一行都应该更改)。 我写了这个函数来打印局部变量,但是当我应用它时,输出不是我想要的

myFunction<- function(x){
              position <- as.data.frame(which(is.na(interval), arr.ind=TRUE))
              tempVar <- ifelse(interval$ID == 1, interval[position$row+1,
                         position$col], interval[position$row-1, position$col])
              return(tempVar)
}

我期待得到这样的东西

# [1]    2
# [2]    2
# [3]    4

但我却把事情搞得一团糟。

这是第 1 次尝试:

dat <- read.table(header=TRUE, text='
V1 V2 V3 ID
NA 1  2  1
2  2  3  2
3  NA 1  3
4  2  2  4
NA 5  1  5')
myfunc1 <- function(x) {
  ind <- which(is.na(x), arr.ind=TRUE)
  # since it appears you want them in row-first sorted order
  ind <- ind[order(ind[,1], ind[,2]),]
  # catch first-row NA
  ind[,1] <- ifelse(ind[,1] == 1L, 2L, ind[,1] - 1L)
  x[ind]
}
myfunc1(dat)
# [1] 2 2 4

问题在于第二个 "stacked" NA:

dat2 <- dat
dat2[2,1] <- NA
dat2
#   V1 V2 V3 ID
# 1 NA  1  2  1
# 2 NA  2  3  2
# 3  3 NA  1  3
# 4  4  2  2  4
# 5 NA  5  1  5
myfunc1(dat2)
# [1] NA NA  2  4

一个fix/safeguard反对这个是使用zoo::na.locf,它采取“last observation carried forward ”。由于顶行是一个特例,我们做了两次,第二次是相反的。这为我们提供了“列中的下一个非 NA 值(向上或向下,视情况而定)。

library(zoo)
myfunc2 <- function(x) {
  ind <- which(is.na(x), arr.ind=TRUE)
  # since it appears you want them in row-first sorted order
  ind <- ind[order(ind[,1], ind[,2]),]
  # this is to guard against stacked NA
  x <- apply(x, 2, zoo::na.locf, na.rm = FALSE)
  # this special-case is when there are one or more NAs at the top of a column
  x <- apply(x, 2, zoo::na.locf, fromLast = TRUE, na.rm = FALSE)
  x[ind]
}
myfunc2(dat2)
# [1] 3 3 2 4