Estou escrevendo uma função que usará a fa()
função do pacote "psych". Quando fa()
falhar na convergência, quero que minha função descarte os resultados e retorne um gráfico vazio que diga apenas "convergência falhou".
Descobri que fa() tem uma warnings=
opção que fará com que ele imprima uma mensagem quando houver falha na convergência, mas não encontrei uma maneira de verificar programaticamente os resultados retornados por fa()
para convergência.
Dentro da minha função, eu faço a chamada fa(...)
passando quaisquer opções para ela que o usuário definiu ao chamar minha função. Então, os usuários podem estar usando diferentes métodos de extração de fatores, diferentes valores para max.iter, etc.
Ao usar o método de extração de fatores do Eixo Principal (por exemplo, fm='pa'
), o objeto retornado por fa()
inclui um vetor de valores produzidos por iterações chamado communality.iterations
, então posso fazer isso:
results <- fa(...)
# Check for Principal Axis factor extraction failing to converge
fa_args <- list(...) # Capture whatever the user gave my function to pass to fa()
if('fm' %in% names(fa_args) && fa_args$fm=='pa') {
max_iter <- ifelse('max.iter' %in% names(fa_args),fa_args$max.iter,50) # 50 is the default if not set
if(length(results$communality.iterations)==max_iter) { # Handle convergence failure
warning('Factor Analysis convergence failed for plot ',plot_title,'.',immediate.=T)
return(ggplot() + theme_void() + labs(title=plot_title,subtitle='Convergence failed'))
}
}
Mas isso abrange apenas um método de extração de fatores que o usuário pode selecionar e o faz de uma forma bastante complicada.
Existe uma maneira melhor de verificar fa()
se há falha na convergência nos resultados?
Nota: Desculpe, não posso fornecer um exemplo reproduzível. Posso dizer pela documentação que outros métodos de extração de fatores, como máxima verossimilhança, podem falhar em convergir, mas não encontrei uma maneira de fazer isso acontecer. Aqui está uma tentativa que não conseguiu produzir um aviso sobre falha de convergência:
library('psych')
bad_corr <- matrix(0,nrow=50,ncol=50)
diag(bad_corr) <- 1
x <- fa(r=bad_corr,nfactors=8,fm='ml',warnings=T)
Difícil sem um exemplo reproduzível, mas:
Olhando para o código, parece que ele
warnings
realmente lança mensagens , em vez de avisos (esses são diferentes). Se o pacote realmente lançou avisos neste caso, você poderia usaroptions(warn = 2)
para escalar avisos para erros, então usartry()
outryCatch()
para interceptá-los e lidar com eles como você achasse adequado.Como esses não são avisos e não há uma maneira equivalente de encaminhar mensagens, você pode tentar usar
capture.output()
around your call tofa()
and usinggrep
(ou ferramentas equivalentes destringr
) para detectar problemas específicos e tomar as medidas apropriadas...