Смещение ведущих ячеек NA влево, но НЕ внутренних NAs в R

#r #dplyr #na #zoo

#r #dplyr #na #зоопарк

Вопрос:

В качестве предисловия я заметил, что существует как минимум 5 ответов на аналогичный вопрос: «Как мне сдвинуть ячейки, отличные от NA, влево». Для этого есть много хороших ответов, и в пакете zoo есть na.locf(), который делает это хорошо.

Моя особая проблема заключается в том, что я хочу сдвинуть ячейки справа от последнего ведущего NA влево, заменив все ведущие NAs. Это означает, что мне нужно сохранить «внутренние» и конечные NAs. Вот небольшой пример с матрицей, но мои реальные данные — это большие данные.frame:

 matrixtest[1, 1:3] <- NA
matrixtest[3, 1:2] <- NA
matrixtest[2, 3] <- NA
matrixtest[4, 2] <- NA
matrixtest

matrixresult <-matrix(4, ncol = 4, nrow = 4)
matrixresult[1, 2:4] <- NA
matrixresult[3, 3:4] <- NA
matrixresult[2, 3] <- NA
matrixresult[4, 2] <- NA
matrixresult
 

После манипуляций matrixtest оригинал должен выглядеть matrixresult
как таковой:

      [,1] [,2] [,3] [,4]
[1,]   NA   NA   NA    4
[2,]    4    4   NA    4
[3,]   NA   NA    4    4
[4,]    4   NA    4    4
> matrixresult
     [,1] [,2] [,3] [,4]
[1,]    4   NA   NA   NA
[2,]    4    4   NA    4
[3,]    4    4   NA   NA
[4,]    4   NA    4    4
 

Прошу прощения, если я уже пропустил соответствующий ответ. Я потратил слишком много времени на эту, казалось бы, простую проблему.

Комментарии:

1. Не могли бы вы подробнее рассказать о том, как работает ваш пример?

2. Col 1: 4 представляют кварталы года. Я пытаюсь выровнять все измерения с их первым, вторым, третьим и т. Д. Измеряемым Временем, А не выравнивать их по календарю. matrixtest <- matrix(4, ncol = 4, nrow = 4) matrixtest[1, 1:3] <- NA matrixtest[3, 1:2] <- NA matrixtest[2, 3] <- NA matrixtest[4, 2] <- NA matrixtest matrixresult <-matrix(4, ncol = 4, nrow = 4) matrixresult[1, 2:4] <- NA matrixresult[3, 3:4] <- NA matrixresult[2, 3] <- NA matrixresult[4, 2] <- NA matrixresult zoomat <- zoo(matrixtest) zoomat <- na.locf(zoomat, fromLast = T)

3. Извините, я не совсем понимаю эту уценку. Но если вы запустите приведенный выше код с соответствующими разрывами строк, чтобы сделать его читаемым, вы получите матрицу, непохожую на матрицу, названную matrixtest выше. Я думаю, что я четко объясняю, но, пожалуйста, дайте мне знать, если я смогу помочь дальше.

Ответ №1:

Мы создаем индекс на основе последнего столбца и rev удаляем эти строки

 i1 <- is.na(matrixresult[, ncol(matrixresult)])
matrixresult[i1, ] <- t(apply(matrixresult[i1,], 1, rev))
 

-вывод

 matrixresult
#     [,1] [,2] [,3] [,4]
#[1,]   NA   NA   NA    4
#[2,]    4    4   NA    4
#[3,]   NA   NA    4    4
#[4,]    4   NA    4    4
 

Ответ №2:

1) shiftLeft удаляет NAs с концов на его входе x , используя na.trim giving y , а затем перезаписывает этим начало вектора NAs. apply это к каждой строке и транспонировать, поскольку apply это приводит к транспонированию того, что мы хотим.

 library(zoo)

shiftLeft <- function(x, y = na.trim(x)) replace(NA * x, seq_along(y), y)
m <- t(apply(matrixtest, 1, shiftLeft))

# check 
identical(m, matrixresult)
## [1] TRUE
 

2) Альтернативой, которая немного длиннее, но включает только базу R, является:

 shiftLeft2 <- function(x) {
  ix <- which.max(!is.na(x))
  replace(NA*x, seq_len(length(x) - ix   1), x[ix:length(x)])
}
m2 <- t(apply(matrixtest, 1, shiftLeft2))
 

Примечание

Мы использовали первую матрицу в качестве входных данных, а вторую — для проверки.

 matrixtest <- structure(c(NA, 4, NA, 4, NA, 4, NA, NA, NA, NA, 4, 4, 4, 4, 
4, 4), .Dim = c(4L, 4L))

matrixresult <- structure(c(4, 4, 4, 4, NA, 4, 4, NA, NA, NA, NA, 4, NA, 4, NA, 
4), .Dim = c(4L, 4L))