Usando funções como entrada para funções com {dbplyr}

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

[ad_1]

Agora vamos tentar chamar nossa função com o mtcars_spark objeto.

mutate_with.tbl_spark

Portanto, obtemos um erro aqui nos informando que passamos uma função subestimada, fn. Isso ocorre porque, em segundo plano, o pacote {dbplyr} está tentando traduzir nosso código para o código Spark SQL a ser executado pelo Spark. Para fazer isso, {dbplyr} analisa nosso código {dplyr}, para o qual há duas partes.

Em primeiro lugar, há a tradução de verbos {dplyr}, por exemplo select(), filter(), arrange()etc. formam a estrutura básica de uma consulta SQL, SELECT, WHERE, ORDER BYetc.

Em segundo lugar, há a tradução das expressões dentro desses verbos. Esta é a parte que nos interessa nesta postagem do blog. Em primeiro lugar, temos “funções conhecidas” em que {dbplyr} pega a funcionalidade que você passa para ele e tenta convertê-la em um equivalente SQL. Como um exemplo simples, {dbplyr} converterá o mean() função para AVG. No entanto, {dbplyr} nem sempre pode produzir uma tradução perfeita porque existem funções que existem em R que não existem nos diversos sabores de SQL, iremos nos referir a elas como “funções desconhecidas”.

Como uma observação, há funcionalidade em ambos que não pode ser traduzida, por exemplo, o trim parâmetro do mean() função não está disponível em SQL.

O que {dbplyr} faz com essas funções desconhecidas, portanto, é deixá-las “como estão”. Isso significa que as funções de banco de dados que não são cobertas por {dbplyr} podem ser usadas diretamente. Por exemplo, no Spark, podemos acessar e usar Hive UDFs.

Então, o que tudo isso significa? E por que isso significa que nossa função falhou? Bem, é porque quando {dbplyr} analisa nosso código, ele “vê” o fn parâmetro e trata-o “como está”, pois não há conversão direta para uma função SQL definida em {dbplyr}. Da mesma forma, não há função no Spark SQL chamada fn() É por isso que, quando nosso código convertido é enviado ao Spark, vemos a falha. Podemos ver isso em ação renderizando a saída traduzida que {dbplyr} nos fornece.

out  SELECT `mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`,
`gear`, `carb`, fn(`mpg`) AS `mean_mpg`
FROM `mtcars`

Isso significa que devemos passar a função real nome, ie mean, no lugar de fn no momento em que {dbplyr} “vê” nosso código e tenta analisá-lo e traduzi-lo em SQL. Para isso, precisamos usar uma semântica de avaliação não padrão.

mutate_with.tbl_spark  [?? x 12]
#      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mean_mpg
#                  
#  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4     20.1
#  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4     20.1
#  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1     20.1
#  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1     20.1
#  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2     20.1
#  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1     20.1
#  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4     20.1
#  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2     20.1
#  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2     20.1
# 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4     20.1
# # … with more rows

Então, por que isso funciona? Bem, o que estamos fazendo aqui é “citar” o parâmetro fn o que é o mesmo que impedir a avaliação de fn. rlang::enquo() é usado para citar argumentos de função como fn e retorna o que é conhecido como “quosure”. Um “quosure” é um objeto que contém a expressão e o ambiente de onde vem essa expressão. Podemos “desquitar” a “questão”, fn, com o !! ou operador “bang-bang”.

Leia Também  Charada: Você pode dizer quando a neve começou?
cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

Em inglês, isso significa que podemos avaliar e substituir inline a expressão capturada. E daí !!fn realmente lê como está mean. O !!fn funciona porque é avaliado antes qualquer código R é avaliado. Em outras palavras, antes que o código seja analisado por {dbplyr}, {rlang} é capaz de avaliar !!fn, substituindo-o por mean. Às vezes, você verá isso sendo referido como avaliação parcial.

São muitas informações em dois parágrafos curtos e eu recomendo fortemente a leitura do arquivo de ajuda (?rlang::quosure) se você gostaria de saber mais. Outro ótimo recurso para aprender mais sobre {rlang} é On Quosures de Brodie Gaslam.

Nós usamos rlang::call2() para construir uma chamada de função entre aspas que pode ser interpretada por {dbplyr}. O que tudo isso se resume a isso rlang::call2(.fn = !!fn, rlang::sym(col_in)) é usado para criar a seguinte expressão não avaliada.

mean(mpg)

Portanto, a ordem de execução é a seguinte:

  1. !!fn é traduzido para mean, em linha.
  2. rlang::call2() é avaliado, dando mean(mpg) (note que convertemos nossa entrada de string em um símbolo usando rlang::sym(col_in))
  3. {dbplyr} traduz o código para código SQL e o envia para o Spark para ser executado.

Observe que podemos obter um resultado semelhante usando base::bquote() e base::eval(). bquote() é o equivalente de base de R da avaliação parcial, que cria uma expressão entre aspas com a qual podemos avaliar eval(). A diferença na sintaxe é que as partes a serem avaliadas parcialmente são cercadas por .() ao invés de !! como em {rlang}.

mutate_with_bquote  [?? x 12]
#      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mean_mpg
#                  
#  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4     20.1
#  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4     20.1
#  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1     20.1
#  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1     20.1
#  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2     20.1
#  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1     20.1
#  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4     20.1
#  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2     20.1
#  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2     20.1
# 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4     20.1
# # … with more rows
Leia Também  Web Scraping Simples e Fácil para Iniciantes em R com {ralger}



[ad_2]

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br