Как исключить НС? (функция фитдиста)
У меня есть кадр данных 100x2 DFN. Бег fitdist
в столбце DFN$Lret выдает сообщение об ошибке "Функция mle не смогла оценить параметры с кодом ошибки 100". Я понял, что причина в том, что последний ряд содержит NA. Отсюда бегаю fitdist
исключая NA, и теперь я получаю ошибку "данные должны быть числовым вектором длиной больше 1". Есть мысли о том, как решить эту проблему? Спасибо большое.
DFN <- structure(list(LRet = c(0.0011, 0, -0.0026, 0, -0.0015, 0.0038, 3e-04, -0.0021, 4e-04, -0.001, 0, 0.0019, -6e-04, -8e-04, -5e-04, -8e-04, 3e-04, -5e-04, -0.0026, 0.0014, 7e-04, 0, -2e-04, 0.0011, -0.0025, 0.0042, 0.0022, -0.0017, -0.0058, 1e-04, 2e-04, 8e-04, -9e-04, -0.0014, -0.0014, -0.001, -0.0032, -0.0015, 6e-04, -8e-04, 0.001, -0.0014, -0.0017, -8e-04, -0.001, 0.0011, 0.0013, -0.001, 5e-04, 9e-04, -8e-04, -0.0025, 0.0027, 6e-04, 2e-04, -6e-04, 9e-04, -3e-04, -7e-04, 3e-04, 0, 2e-04, -6e-04, 1e-04, -1e-04, -7e-04, -8e-04, 7e-04, -1e-04, -7e-04, 7e-04, 8e-04, -8e-04, 8e-04, 0.0058, -1e-04, -5e-04, 0.0027, -0.0012, 7e-04, 7e-04, 0, 3e-04, -1e-04, 2e-04, -2e-04, -0.0013, -1e-04, 1e-04, -0.0011, 0.0013, 2e-04, -3e-04, -7e-04, 0, 0.0015, 1e-04, 3e-04, -0.0012, NA), LRetPct = c("0.11%", "0.00%", "-0.26%", "0.00%", "-0.15%", "0.38%", "0.03%", "-0.21%", "0.04%", "-0.10%", "0.00%", "0.19%", "-0.06%", "-0.08%", "-0.05%", "-0.08%", "0.03%", "-0.05%", "-0.26%", "0.14%", "0.07%", "0.00%", "-0.02%", "0.11%", "-0.25%", "0.42%", "0.22%", "-0.17%", "-0.58%", "0.01%", "0.02%", "0.08%", "-0.09%", "-0.14%", "-0.14%", "-0.10%", "-0.32%", "-0.15%", "0.06%", "-0.08%", "0.10%", "-0.14%", "-0.17%", "-0.08%", "-0.10%", "0.11%", "0.13%", "-0.10%", "0.05%", "0.09%", "-0.08%", "-0.25%", "0.27%", "0.06%", "0.02%", "-0.06%", "0.09%", "-0.03%", "-0.07%", "0.03%", "0.00%", "0.02%", "-0.06%", "0.01%", "-0.01%", "-0.07%", "-0.08%", "0.07%", "-0.01%", "-0.07%", "0.07%", "0.08%", "-0.08%", "0.08%", "0.58%", "-0.01%", "-0.05%", "0.27%", "-0.12%", "0.07%", "0.07%", "0.00%", "0.03%", "-0.01%", "0.02%", "-0.02%", "-0.13%", "-0.01%", "0.01%", "-0.11%", "0.13%", "0.02%", "-0.03%", "-0.07%", "0.00%", "0.15%", "0.01%", "0.03%", "-0.12%", " NA%")), .Names = c("LRet", "LRetPct"), class = "data.frame", row.names = 901:1000)
library(fitdistrplus)
#Following gives error code 100
f1 <- fitdist(DFN$LRet,"norm")
#Following gives error code 100
f1 <- fitdist(DFN$LRet,"norm", na.rm=T)
#Following gives error data must be a numeric vector of length greater than 1"
f1 <- fitdist(na.exclude(DFN$LRet),"norm")
#Same result using na.omit
Обратите внимание: если вы удалите последнюю строку, содержащую NA, приведенный выше код работает нормально. Я бы предпочел не удалять последний ряд перед запуском fitdist
если можно избежать
РЕДАКТИРОВАНИЕ / ОБНОВЛЕНИЕ: удаление последней строки с помощью NA действительно решило проблему вначале, но теперь я не могу воспроизвести это последовательно (то есть успешно выполнил код несколько раз после удаления последней строки, но не всегда). Я пытаюсь понять почему. Я попытался использовать фрейм данных 25x2, 100x2 и 300x2, а также вектор, с похожими результатами. Он думал, что размер фрейма данных или вектора может быть частью проблемы, отсюда и испытания с разными размерами.
2 ответа
(Также нашел плохо написано is.vector
раздел кода, но это не решило ошибки.) fitdist
Кажется, что функция имеет проблемы с векторами малой дисперсии:
var( na.exclude(DFN$LRet))
[1] 2.220427e-06
Вы можете обойти это, умножив на 10:
> f1 <- fitdist(10*c(na.exclude(DFN$LRet)),"norm")
> f1
Fitting of the distribution ' norm ' by maximum likelihood
Parameters:
estimate Std. Error
mean -0.0009090909 0.001490034
sd 0.0148256472 0.001032122
Стандартная теория вероятностей позволяет затем корректировать эти оценки: разделить на 10 для среднего значения и на 100 для дисперсии (или 10 для sd). Оценки от исправленных fitdist
- результаты достаточно близки к значениям выборки:
> all.equal( 0.0148256472/10 , sd(na.exclude(DFN$LRet) ) )
[1] "Mean relative difference: 0.005089095"
Отладка через fitdist
шоу
if (!(is.vector(data) & is.numeric(data) & length(data) > 1))
stop("data must be a numeric vector of length greater than 1")
Смотря на ?is.vector
:
"is.vector" возвращает "TRUE", если "x" - это вектор указанного режима, не имеющий никаких атрибутов, кроме имен.
na.exclude
и его родственники (na.omit
и т. д.) сохранить информацию об исключенных значениях как атрибут, is.vector()
становится FALSE
...
Один из побочных эффектов c()
это удалить атрибуты, отличные от имен, так is.vector(c(na.exclude(DFN$LRet)))
является TRUE
, так
fitdist(c(na.exclude(DFN$LRet)), "norm")
по крайней мере, не появляется ошибка "должен быть числовой вектор", но я все равно получаю "ошибку 100". Расследование дальше...
Копаться в кишках fitdist
еще немного, кажется, что (как предложено @42-) optim()
возникают проблемы. В частности, он действительно получает ответ, но когда он пытается вычислить гессиан решения, он пытается получить отрицательное значение для параметра стандартного отклонения и barfs.
В качестве иллюстрации это работает:
nn <- c(na.exclude(DFN$LRet))
fn <- function(x) -sum(dnorm(nn,mean=x[1],sd=x[2],log=TRUE))
optim(fn,par=c(mean(nn),sd(nn)),method="Nelder-Mead")
но это не удается
optim(fn,par=c(mean(nn),sd(nn)),method="Nelder-Mead",hessian=TRUE)