#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))