Ввести недостающие значения с ограничениями репликации в R
Я анализирую долгосрочный набор данных по метке-повторной поимке животных, в котором захваченные особи назначаются в 1 из 5 классов размера при каждом захвате. Мне нужно создать матрицу, которая интерполирует между известными значениями и за их пределами (т. Е. Годы, в течение которых животное наблюдалось) И включает ограничения на то, как долго человек может оставаться в каждом классе размеров.
Ниже приведены пять историй захвата выборки (СН; отдельные = строки), охватывающих 20 лет (столбцы). Существует пять числовых кодов возможных классов размеров (1= наименьший). NA - это годы, когда животное не было поймано (здесь рассматриваются как отсутствующие значения).
Люди могут впервые наблюдаться в любом классе размеров (например, строка 1 против строки 3), и мы можем повторно поймать людей, которые пропустили класс размера (например, строка 2).
CH <- rbind(c(NA,NA,1,2,rep(NA,7),3,rep(NA,8)),
c(1,rep(NA,9),3,NA,NA,3,rep(NA,6)),
c(rep(NA,10),4,NA,NA,5,rep(NA,6)),
c(3,rep(NA,17),5,NA),
c(rep(NA,7),2,rep(NA,8),4,rep(NA,3)))
CH
> CH
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,] NA NA 1 2 NA NA NA NA NA NA NA 3 NA NA NA NA NA NA NA NA
[2,] 1 NA NA NA NA NA NA NA NA NA 3 NA NA 3 NA NA NA NA NA NA
[3,] NA NA NA NA NA NA NA NA NA NA 4 NA NA 5 NA NA NA NA NA NA
[4,] 3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 5 NA
[5,] NA NA NA NA NA NA NA 2 NA NA NA NA NA NA NA NA 4 NA NA NA
Я выяснил, как интерполировать значения без ограничений, используя функцию na.interpolation() в пакете imputeTS, показанном ниже:
#ImputeTS missing values (with NO constraints, not ideal)
library(imputeTS)
ms.init.z <- function(ms, notseen){
state <- ms # capture history called state
for(i in 1:dim(state)[1]){ #Do this for every row/individual
if(any(!is.na(state[i,1:dim(state)[2]-1]))){ #If any are not NA through the 2nd to last occs'n
state[i,dim(state)[2]] <- max(state[i,],na.rm=TRUE) #Apply max state value for that individual to final year
#populate last column as as.interpolation needs at least two values
state[i,] <- ceiling(na.interpolation(state[i,])) # interpolate
} #if
m <- min(which(!is.na(ms[i,]))) #identify the first occasion not NA
state[i,1:(m-1)] <- NA #Replace before and on first occasion with NA
} #i
return(state)
} #function
CH.X <- ms.init.z(CH,NA)
> CH.X
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,] NA NA 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[2,] NA 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[3,] NA NA NA NA NA NA NA NA NA NA 4 5 5 5 5 5 5 5 5 5
[4,] NA 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5
[5,] NA NA NA NA NA NA NA 2 3 3 3 3 4 4 4 4 4 4 4 4
Тем не менее, я хотел бы установить ограничения на то, сколько лет человек может оставаться в каждом классе размера. Я изо всех сил пытаюсь найти пакет, который позволил бы мне реализовать настроенные ограничения.
Мой "идеальный" вывод показан ниже. Обратите внимание, что существует более одного решения для большей части (всех?) Каждой строки, и это хорошо, если число наблюдений в каждом классе размеров не превышает максимум (указанный ниже).
#Desired constraints (maximum # of years in each size)
#Size class 1= 1 year max; 2= 7 yrs max; 3= 7 yrs max;
#4= 15 yrs max; 5= no limit
#Example Desired output
CH.cor <- rbind(c(NA,NA,1,rep(2,5),rep(3,6),rep(4,6)),
c(1,rep(2,6),rep(3,7),rep(4,6)),
c(rep(4,12),rep(5,8)),
c(rep(3,3),rep(4,15),5,5),
c(rep(NA,6),1,rep(2,7),rep(3,6)))
CH.cor
> CH.cor
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,] NA NA 1 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
[2,] 1 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4
[3,] 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5
[4,] 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5
[5,] NA NA NA NA NA NA 1 2 2 2 2 2 2 2 3 3 3 3 3 3
Любой совет или помощь будет высоко ценится. Заранее спасибо.
1 ответ
Вы, вероятно, не найдете пакет, который предлагает вам это функционально из коробки.
У меня есть совет по использованию пакета imputeTS:
Если вы хотите поддерживать NA в начале при использовании na.interpolation, вы можете использовать следующую опцию:
library("imputeTS")
na.interpolation(x, yleft = NA)
Это сэкономит вам 6 строк кода в приведенном выше примере.
Но для вашей проблемы вам, вероятно, это не понадобится. Мне кажется, лучший вариант - программировать собственное решение. Так как ваши требования очень специфичны.