Функция для присвоения значения ячейки последующим ячейкам NA (тот же столбец)

Спасибо, что уделили время моей проблеме! Я новичок на форуме и относительно новичок в R, но я сделаю все возможное, чтобы четко сформулировать вопрос.

У меня есть большой набор выборочных данных дерева с нерегулярным количеством строк на человека. В столбце переменной «класс» (здесь столбец 2) первая строка каждого человека имеет значение (1, 2, 3 или 4), а последующие - NA. Я хотел бы присвоить первое значение каждого человека соответствующим последующим ячейкам NA (принадлежащим одному и тому же человеку).

Воспроизводимый пример кадра данных (отредактированный):

test <- cbind(c(1, 2, 3, NA, 4, NA, NA, NA, 5, NA, 6), c(3, 4, 3, NA, 1, NA, NA, NA, 2, NA, 1))
colnames(test) <- c("ID", "class")

        ID  class
 [1,]    1    3
 [2,]    2    4
 [3,]    3    3
 [4,]   NA   NA
 [5,]    4    1
 [6,]   NA   NA
 [7,]   NA   NA
 [8,]   NA   NA
 [9,]    5    2
[10,]   NA   NA
[11,]    6    1

Результат, который я ищу, таков:

      ID class
 [1,]  1     3
 [2,]  2     4
 [3,]  3     3
 [4,] NA     3
 [5,]  4     1
 [6,] NA     1
 [7,] NA     1
 [8,] NA     1
 [9,]  5     2
[10,] NA     2
[11,]  6     1

Я скопировал последнее решение из этой темы Как заменить несколько NA значениями в DF, используя if-else в R? и попытался адаптировать его к моим потребностям, как это

    test2 <- as.data.frame(t(apply(test["class"], 1, function(x)
    if(is.na(x[1]) == FALSE && all(is.na(head(x[1], -1)[-1])))
    replace(x, is.na(x), x[1]) else x)))

но это дает мне ошибку «dim (x) должен иметь положительную длину». Пробовал много других версий и выдает всякие ошибки, даже не знаю с чего начать. Как я могу улучшить его?


person Brazza    schedule 03.03.2015    source источник
comment
Я бы использовал функцию na.locf (из пакета zoo) или альтернатива base-R для распространения предыдущего значения на последовательные NA... т.е. test[,2] <- na.locf(test[,2])   -  person digEmAll    schedule 04.03.2015


Ответы (1)


Вот небольшая однострочная функция, которая будет работать, если вы не хотите загружать другой пакет:

rollForward <- function(x) {
    c(NA, x[!is.na(x)])[cumsum(!is.na(x)) + 1]
}

test[,"class"] <- rollForward(test[,"class"])
test
#       ID class
#  [1,]  1     3
#  [2,]  2     4
#  [3,]  3     3
#  [4,] NA     3
#  [5,]  4     1
#  [6,] NA     1
#  [7,] NA     1
#  [8,] NA     1
#  [9,]  5     2
# [10,] NA     2
# [11,]  6     1
person Josh O'Brien    schedule 03.03.2015
comment
Большое спасибо, Джош, это решает проблему! - person Brazza; 04.03.2015