Considere o seguinte código:
> df <- tibble(gender=c(1,1,0))
> df$male
Warning: Unknown or uninitialised column: `male`.
NULL
Como posso converter esse tipo de aviso específico em um erro?
Gostaria de algo assim options(warn = 2)
, mas apenas para esse tipo específico de aviso (ou seja, referindo-se a uma coluna em um tibble que não existe)
É um pouco hackeado, mas você pode corrigir a função
$
, ou seja, o getter. O aviso é lançado porrlang::warn
quando o nome da coluna não é encontrado emdf
. Ao substituir esta chamada por uma pararlang::abort
transformamos este aviso em um erro.A função original para o método S3
$.tbl_df
é definida como:Você pode simplesmente substituir o aviso por um erro usando
stop
ourlang:abort()
:Então, como esperado:
Adenda
Conforme apontado nos comentários, essa solução pode causar problemas se
$.tbl_df
estiver sendo chamada internamente. Seguindo o exemplo de @Billy34, podemos substituir a$.tbl_df
função interna pela nossa função modificada assim:Isso produz a saída:
Com base na ideia da resposta de @BenBolker, você pode criar um manipulador global:
Claro que isso seria mais simples se o aviso fosse classificado.
Isso pode ser o mais próximo que você chegará (sem hackear como na resposta anterior): use um
tryCatch()
que verifique a mensagem de aviso (isso falhará se alguém usar configurações de idioma diferentes para onde o aviso foi traduzido).Outros lhe deram soluções alternativas para esse problema. Nesta resposta, explicarei o que os
tibble
autores poderiam ter feito para facilitar o trabalho.R tem suporte para erros e avisos classificados, mas eles não são muito usados. O
rlang
pacote tem oclass
argumento para cada um deabort()
,warn()
einform()
. Você não precisa usarrlang
, tudo pode ser feito com funções base, mas elas empacotam bem.Então o que
tibble
poderia ter feito é definir uma classe separada em cada aviso que eles emitem. Então você poderia capturar a classe específica correspondente ao aviso que lhe interessa e convertê-la em um erro. Ou você poderia criar seu próprio$.tbl_df
método que faz isso e então escolher se quer ou não a conversão.Por exemplo, em vez de
eles poderiam ter escrito
e então você poderia correr
para capturar esse aviso e convertê-lo em um erro. Eu converti para um erro de classe com class
"error.$.tbl_df"
apenas para que algum outro código pudesse capturar isso, mas não há necessidade disso. Eu também configureicall = NULL
para que você não seja informado sobre uma linha no código$.tbl_df
que não significaria nada para você. Você pode ser capaz de encontrar adf$male
expressão se brincar com a configuração; não tenho certeza de quão longe ela estaria.