Neste tuturial iremos mostrar como o comportamento de NAs
no R é consistente com o de NULL
no PostgreSQL.
Quando você envia um dataframe do R para PostgreSQL, NAs
, ou seja, valores faltantes, são convertidos para NULL
. Acontece que o R diferencia NA
de NULL
. No R NULL
é tipo de objeto e é por isso que você não consegue incluí-lo num vetor ou numa matriz, mas consegue adicioná-lo como elemento numa lista, inclusive em dataframes, já que estas também são listas. Porém, somente quando todas as colunas são NULL
. NULL
no R é um tanto ambíguo, pois ora se comporta como vazio, ora como elemento indefinido.
Por sua vez, NA
no R é um elemento lógico para indicar dado desconhecido. Isso é concebido dentro da lógica ternária, que admite três valores: VERDADEIRO, FALSO e DESCONHECIDO. O mesmo acontece com SQL para NULL
.
Neste tuturial iremos mostrar como o comportamento de NAs
no R é consistente com o de NULL
no PostgreSQL.
Para criar objetos com valores desconhecidos no R, você simplesmente coloca NA
no vetor ou na coluna:
a <- c(1,2,3,NA)
a
[1] 1 2 3 NA
df <- data.frame(a = a)
df
a
1 1
2 2
3 3
4 NA
No PostgreSQL, você pode fazer o mesmo, mas com NULL
a
1
2
3
(4 rows)
a
1
2
3
(4 rows)
Como ambos são valores desconhecidos, espera-se que o comportamento seja similar num e noutro, e de fato é, em muitas situações.
2 == NA
[1] NA
NA == NA
[1] NA
2 < NA
[1] NA
2 + NA
[1] NA
Em todas essas situações, o R retorna o elemento lógico NA
, ou seja, desconhecido, porque o resultado da comparação é de fato desconhecido, já que NA
pode equivaler a uma infinidade de valores, inclusive o valor comparado a NA
.
Como NULL
possui a mesma natureza, as respostas são consistentes:
?column?
(1 row)
?column?
(1 row)
?column?
(1 row)
?column?
(1 row)
Igualmente, algo que surpreende no R é o filtro negativo em colunas que contêm NAs
:
subset(df,a !=2)
a
1 1
3 3
Com dplyr ocorre o mesmo:
dplyr::filter(df,a != 2)
a
1 1
2 3
Em ambos os casos, linhas com NAs
também foram excluídas. Isso porque NA
pode conter o 2 (Confesso que esse comportamento não me convence inteiramente).
Vejamos em SQL
a
1
3
(2 rows)
Para evitar surpresas, não se esqueça de explicitamente filtrar para NAs
no R e para NULLs
no PostgreSQL.
a
1
3
(3 rows)
Não estou absolutamente seguro de que os comportamentos de NA
no R e NULL
em SQL são sempre os mesmos, mas para as operações mais comuns, você pode ficar tranquila que são.