Проблема с локальными переменными в пользовательской функции r - PullRequest
0 голосов
/ 28 июня 2018

У меня есть набор данных

>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 Ответ

0 голосов
/ 28 июня 2018

Вот попытка номер 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

Проблема в том, что есть вторая "стопка" 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

Одним из способов устранения / защиты от этого является использование zoo::na.locf, которое принимает «l ast o bservation c arried f orward». Поскольку верхний ряд является особым случаем, мы делаем это дважды, второй раз наоборот. Это дает нам «следующее не 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
...