Pular para o conteúdo principal

Trabalhar com DataFrames e tabelas no R

importante

SparkR em Databricks está obsoleto em Databricks Runtime 16.0 e acima. Databricks recomenda o uso de Sparklyr em vez disso.

Este artigo descreve como usar pacotes do R, como SparkR, Sparklyre dplyr para trabalhar com R data.frames, Spark DataFramese tabelas na memória.

Observe que, ao trabalhar com SparkR, Sparklyr e dplyr, você poderá descobrir que pode concluir uma determinada operação com todos esses pacotes e usar o pacote com o qual se sente mais confortável. Por exemplo, para executar uma consulta, o senhor pode chamar funções como SparkR::sql, sparklyr::sdf_sql, e dplyr::select. Em outras ocasiões, o senhor poderá concluir uma operação com apenas um ou dois desses pacotes, e a operação escolhida depende do cenário de uso. Por exemplo, a maneira como você chama sparklyr::sdf_quantile difere um pouco da maneira como você chama dplyr::percentile_approx, embora ambas as funções calculem quantis.

O senhor pode usar o site SQL como uma ponte entre SparkR e Sparklyr. Por exemplo, o senhor pode usar SparkR::sql para consultar tabelas que criou com Sparklyr. O senhor pode usar o site sparklyr::sdf_sql para consultar as tabelas que criar com o SparkR. E o código dplyr sempre é traduzido para SQL na memória antes de ser executado. Consulte também Interoperabilidade de API e Tradução de SQL.

Carregue SparkR, Sparklyr e dplyr​

Os SparkR Sparklyrpacotes, e dplyr estão incluídos no Databricks Runtime que está instalado no Databricks cluster. Portanto, o senhor não precisa acessar o site install.package antes de começar a acessar esse pacote. No entanto, o senhor ainda deve carregar esses pacotes com library primeiro. Por exemplo, em um Notebook do R em Databricks workspace, execute o seguinte código em uma célula do Notebook para carregar SparkR, Sparklyr e dplyr:

R
library(SparkR)
library(sparklyr)
library(dplyr)

Conecte o site Sparklyr a um clustering​

Depois de carregar Sparklyr, o senhor deve chamar sparklyr::spark_connect para se conectar ao clustering, especificando o método de conexão databricks. Por exemplo, execute o seguinte código em uma célula do Notebook para se conectar ao clustering que hospeda o Notebook:

sc <- spark_connect(method = "databricks")

Por outro lado, um Notebook Databricks já estabelece um SparkSession no clustering para uso com SparkR, de modo que o senhor não precisa chamar SparkR::sparkR.session antes de começar a chamar SparkR.

Carregue um arquivo de dados JSON em seu workspace​

Muitos dos exemplos de código neste artigo são baseados em dados em um local específico em seu site Databricks workspace, com nomes de colunas e tipos de dados específicos. Os dados para este exemplo de código são originados em um arquivo JSON chamado book.json de dentro do GitHub. Para obter esse arquivo e upload em seu site workspace:

  1. Acesse o arquivo books.JSON em GitHub e use um editor de texto para copiar seu conteúdo para um arquivo chamado books.json em algum lugar do computador local.
  2. Na barra lateral do site Databricks workspace , clique em Catalog (Catálogo ).
  3. Clique em Criar > Fazer upload para volume .
  4. Na caixa de diálogo Upload files , solte o arquivo books.json de sua máquina local na caixa Drop files to upload . Ou selecione click to browse e navegue até o arquivo books.json em sua máquina local.
  5. Selecione um Volume de destino e clique em Upload .

Copie o caminho do arquivo de volume, por exemplo, /Volumes/my_catalog/my_schema/my_volume/books.json.

Ler os dados JSON em um DataFrame​

Use sparklyr::spark_read_json para ler o arquivo de upload JSON em um DataFrame, especificando a conexão, o caminho para o arquivo JSON e um nome para a representação da tabela interna dos dados. Neste exemplo, você deve especificar que o arquivo book.json contém várias linhas. Especificar o esquema das colunas aqui é opcional. Caso contrário, Sparklyr infere o esquema das colunas por default. Por exemplo, execute o seguinte código em uma célula do Notebook para ler os dados do arquivo de upload JSON em um DataFrame chamado jsonDF:

R
jsonDF <- spark_read_json(
sc = sc,
name = "jsonTable",
path = "/Volumes/my_catalog/my_schema/my_volume/books.json",
options = list("multiLine" = TRUE),
columns = c(
author = "character",
country = "character",
imageLink = "character",
language = "character",
link = "character",
pages = "integer",
title = "character",
year = "integer"
)
)

Imprimir as primeiras linhas de um DataFrame​

O senhor pode usar SparkR::head, SparkR::show ou sparklyr::collect para imprimir as primeiras linhas de um DataFrame. Por default, head imprime as seis primeiras linhas por default. show e collect imprimem as primeiras 10 linhas. Por exemplo, execute o seguinte código em uma célula do Notebook para imprimir as primeiras linhas do site DataFrame chamado jsonDF:

R
head(jsonDF)

# Source: spark<?> [?? x 8]
# author country image…¹ langu…² link pages title year
# <chr> <chr> <chr> <chr> <chr> <int> <chr> <int>
# 1 Chinua Achebe Nigeria images… English "htt… 209 Thin… 1958
# 2 Hans Christian Andersen Denmark images… Danish "htt… 784 Fair… 1836
# 3 Dante Alighieri Italy images… Italian "htt… 928 The … 1315
# 4 Unknown Sumer and Akk… images… Akkadi… "htt… 160 The … -1700
# 5 Unknown Achaemenid Em… images… Hebrew "htt… 176 The … -600
# 6 Unknown India/Iran/Ir… images… Arabic "htt… 288 One … 1200
# … with abbreviated variable names ¹​imageLink, ²​language

show(jsonDF)

# Source: spark<jsonTable> [?? x 8]
# author country image…¹ langu…² link pages title year
# <chr> <chr> <chr> <chr> <chr> <int> <chr> <int>
# 1 Chinua Achebe Nigeria images… English "htt… 209 Thin… 1958
# 2 Hans Christian Andersen Denmark images… Danish "htt… 784 Fair… 1836
# 3 Dante Alighieri Italy images… Italian "htt… 928 The … 1315
# 4 Unknown Sumer and Ak… images… Akkadi… "htt… 160 The … -1700
# 5 Unknown Achaemenid E… images… Hebrew "htt… 176 The … -600
# 6 Unknown India/Iran/I… images… Arabic "htt… 288 One … 1200
# 7 Unknown Iceland images… Old No… "htt… 384 Njál… 1350
# 8 Jane Austen United Kingd… images… English "htt… 226 Prid… 1813
# 9 Honoré de Balzac France images… French "htt… 443 Le P… 1835
# 10 Samuel Beckett Republic of … images… French… "htt… 256 Moll… 1952
# … with more rows, and abbreviated variable names ¹​imageLink, ²​language
# ℹ Use `print(n = ...)` to see more rows

collect(jsonDF)

# A tibble: 100 × 8
# author country image…¹ langu…² link pages title year
# <chr> <chr> <chr> <chr> <chr> <int> <chr> <int>
# 1 Chinua Achebe Nigeria images… English "htt… 209 Thin… 1958
# 2 Hans Christian Andersen Denmark images… Danish "htt… 784 Fair… 1836
# 3 Dante Alighieri Italy images… Italian "htt… 928 The … 1315
# 4 Unknown Sumer and Ak… images… Akkadi… "htt… 160 The … -1700
# 5 Unknown Achaemenid E… images… Hebrew "htt… 176 The … -600
# 6 Unknown India/Iran/I… images… Arabic "htt… 288 One … 1200
# 7 Unknown Iceland images… Old No… "htt… 384 Njál… 1350
# 8 Jane Austen United Kingd… images… English "htt… 226 Prid… 1813
# 9 Honoré de Balzac France images… French "htt… 443 Le P… 1835
# 10 Samuel Beckett Republic of … images… French… "htt… 256 Moll… 1952
# … with 90 more rows, and abbreviated variable names ¹​imageLink, ²​language
# ℹ Use `print(n = ...)` to see more rows

execução SQL consultas, gravação e leitura de uma tabela​

O senhor pode usar as funções do dplyr para executar SQL consultas em um DataFrame. Por exemplo, execute o seguinte código em uma célula do Notebook para usar dplyr::group_by e dployr::count para obter contagens por autor no site DataFrame chamado jsonDF. Use dplyr::arrange e dplyr::desc para classificar o resultado em ordem decrescente por contagens. Em seguida, imprima as 10 primeiras linhas em default.

R
group_by(jsonDF, author) %>%
count() %>%
arrange(desc(n))

# Source: spark<?> [?? x 2]
# Ordered by: desc(n)
# author n
# <chr> <dbl>
# 1 Fyodor Dostoevsky 4
# 2 Unknown 4
# 3 Leo Tolstoy 3
# 4 Franz Kafka 3
# 5 William Shakespeare 3
# 6 William Faulkner 2
# 7 Gustave Flaubert 2
# 8 Homer 2
# 9 Gabriel García Márquez 2
# 10 Thomas Mann 2
# … with more rows
# ℹ Use `print(n = ...)` to see more rows

O senhor poderia então usar o site sparklyr::spark_write_table para gravar o resultado em uma tabela no Databricks. Por exemplo, execute o código a seguir em uma célula do Notebook para executar novamente a consulta e, em seguida, gravar o resultado em uma tabela chamada json_books_agg:

R
group_by(jsonDF, author) %>%
count() %>%
arrange(desc(n)) %>%
spark_write_table(
name = "json_books_agg",
mode = "overwrite"
)

Para verificar se a tabela foi criada, você pode usar sparklyr::sdf_sql junto com SparkR::showDF para exibir os dados da tabela. Por exemplo, execute o seguinte código em uma célula do Notebook para consultar a tabela em um DataFrame e, em seguida, use sparklyr::collect para imprimir as 10 primeiras linhas do DataFrame por default:

R
collect(sdf_sql(sc, "SELECT * FROM json_books_agg"))

# A tibble: 82 × 2
# author n
# <chr> <dbl>
# 1 Fyodor Dostoevsky 4
# 2 Unknown 4
# 3 Leo Tolstoy 3
# 4 Franz Kafka 3
# 5 William Shakespeare 3
# 6 William Faulkner 2
# 7 Homer 2
# 8 Gustave Flaubert 2
# 9 Gabriel García Márquez 2
# 10 Thomas Mann 2
# … with 72 more rows
# ℹ Use `print(n = ...)` to see more rows

Você também pode usar sparklyr::spark_read_table para fazer algo semelhante. Por exemplo, execute o seguinte código em uma célula do Notebook para consultar o DataFrame anterior denominado jsonDF em um DataFrame e, em seguida, use sparklyr::collect para imprimir as 10 primeiras linhas do DataFrame por default:

R
fromTable <- spark_read_table(
sc = sc,
name = "json_books_agg"
)

collect(fromTable)

# A tibble: 82 × 2
# author n
# <chr> <dbl>
# 1 Fyodor Dostoevsky 4
# 2 Unknown 4
# 3 Leo Tolstoy 3
# 4 Franz Kafka 3
# 5 William Shakespeare 3
# 6 William Faulkner 2
# 7 Homer 2
# 8 Gustave Flaubert 2
# 9 Gabriel García Márquez 2
# 10 Thomas Mann 2
# … with 72 more rows
# ℹ Use `print(n = ...)` to see more rows

Adicione colunas e compute valores de coluna em um DataFrame​

O senhor pode usar as funções do dplyr para adicionar colunas a DataFrames e para compute os valores das colunas.

Por exemplo, execute o seguinte código em uma célula do Notebook para obter o conteúdo do site DataFrame chamado jsonDF. Use dplyr::mutate para adicionar uma coluna chamada today e preencha essa nova coluna com o carimbo de data/hora atual. Em seguida, grave esse conteúdo em um novo DataFrame chamado withDate e use dplyr::collect para imprimir as primeiras 10 linhas do novo DataFrame por default.

nota

dplyr::mutate aceita apenas argumentos que estejam em conformidade com Hive as funções integradas (também conhecidas como UDFs) e funções agregadas integradas (também conhecidas como)UDAFs do site. Para obter informações gerais, consulte Hive Functions. Para obter informações sobre as funções relacionadas à data nesta seção, consulte Funções de data.

R
withDate <- jsonDF %>%
mutate(today = current_timestamp())

collect(withDate)

# A tibble: 100 × 9
# author country image…¹ langu…² link pages title year today
# <chr> <chr> <chr> <chr> <chr> <int> <chr> <int> <dttm>
# 1 Chinua A… Nigeria images… English "htt… 209 Thin… 1958 2022-09-27 21:32:59
# 2 Hans Chr… Denmark images… Danish "htt… 784 Fair… 1836 2022-09-27 21:32:59
# 3 Dante Al… Italy images… Italian "htt… 928 The … 1315 2022-09-27 21:32:59
# 4 Unknown Sumer … images… Akkadi… "htt… 160 The … -1700 2022-09-27 21:32:59
# 5 Unknown Achaem… images… Hebrew "htt… 176 The … -600 2022-09-27 21:32:59
# 6 Unknown India/… images… Arabic "htt… 288 One … 1200 2022-09-27 21:32:59
# 7 Unknown Iceland images… Old No… "htt… 384 Njál… 1350 2022-09-27 21:32:59
# 8 Jane Aus… United… images… English "htt… 226 Prid… 1813 2022-09-27 21:32:59
# 9 Honoré d… France images… French "htt… 443 Le P… 1835 2022-09-27 21:32:59
# 10 Samuel B… Republ… images… French… "htt… 256 Moll… 1952 2022-09-27 21:32:59
# … with 90 more rows, and abbreviated variable names ¹​imageLink, ²​language
# ℹ Use `print(n = ...)` to see more rows

Agora, use o site dplyr::mutate para adicionar mais duas colunas ao conteúdo do DataFrame withDate. As novas colunas month e year contêm o mês e o ano numéricos da coluna today. Em seguida, grave esse conteúdo em um novo DataFrame chamado withMMyyyy e use dplyr::select junto com dplyr::collect para imprimir as colunas author, title, month e year das dez primeiras linhas do novo DataFrame por default:

R
withMMyyyy <- withDate %>%
mutate(month = month(today),
year = year(today))

collect(select(withMMyyyy, c("author", "title", "month", "year")))

# A tibble: 100 × 4
# author title month year
# <chr> <chr> <int> <int>
# 1 Chinua Achebe Things Fall Apart 9 2022
# 2 Hans Christian Andersen Fairy tales 9 2022
# 3 Dante Alighieri The Divine Comedy 9 2022
# 4 Unknown The Epic Of Gilgamesh 9 2022
# 5 Unknown The Book Of Job 9 2022
# 6 Unknown One Thousand and One Nights 9 2022
# 7 Unknown Njál's Saga 9 2022
# 8 Jane Austen Pride and Prejudice 9 2022
# 9 Honoré de Balzac Le Père Goriot 9 2022
# 10 Samuel Beckett Molloy, Malone Dies, The Unnamable, the … 9 2022
# … with 90 more rows
# ℹ Use `print(n = ...)` to see more rows

Agora, use o site dplyr::mutate para adicionar mais duas colunas ao conteúdo do DataFrame withMMyyyy. As novas colunas formatted_date contêm a parte yyyy-MM-dd da coluna today, enquanto a nova coluna day contém o dia numérico da nova coluna formatted_date. Em seguida, grave esse conteúdo em um novo DataFrame chamado withUnixTimestamp e use dplyr::select juntamente com dplyr::collect para imprimir as colunas title, formatted_date e day das dez primeiras linhas do novo DataFrame por default:

R
withUnixTimestamp <- withMMyyyy %>%
mutate(formatted_date = date_format(today, "yyyy-MM-dd"),
day = dayofmonth(formatted_date))

collect(select(withUnixTimestamp, c("title", "formatted_date", "day")))

# A tibble: 100 × 3
# title formatted_date day
# <chr> <chr> <int>
# 1 Things Fall Apart 2022-09-27 27
# 2 Fairy tales 2022-09-27 27
# 3 The Divine Comedy 2022-09-27 27
# 4 The Epic Of Gilgamesh 2022-09-27 27
# 5 The Book Of Job 2022-09-27 27
# 6 One Thousand and One Nights 2022-09-27 27
# 7 Njál's Saga 2022-09-27 27
# 8 Pride and Prejudice 2022-09-27 27
# 9 Le Père Goriot 2022-09-27 27
# 10 Molloy, Malone Dies, The Unnamable, the trilogy 2022-09-27 27
# … with 90 more rows
# ℹ Use `print(n = ...)` to see more rows

Criar um view​

O senhor pode criar visualizações temporárias nomeadas na memória que são baseadas em DataFrames. Por exemplo, execute o código a seguir em uma célula do Notebook para usar SparkR::createOrReplaceTempView para obter o conteúdo do DataFrame anterior chamado jsonTable e criar um view temporário com o nome timestampTable. Em seguida, use sparklyr::spark_read_table para ler o conteúdo temporário de view. Use sparklyr::collect para imprimir as 10 primeiras linhas da tabela temporária por default:

R
createOrReplaceTempView(withTimestampDF, viewName = "timestampTable")

spark_read_table(
sc = sc,
name = "timestampTable"
) %>% collect()

# A tibble: 100 × 10
# author country image…¹ langu…² link pages title year today
# <chr> <chr> <chr> <chr> <chr> <int> <chr> <int> <dttm>
# 1 Chinua A… Nigeria images… English "htt… 209 Thin… 1958 2022-09-27 21:11:56
# 2 Hans Chr… Denmark images… Danish "htt… 784 Fair… 1836 2022-09-27 21:11:56
# 3 Dante Al… Italy images… Italian "htt… 928 The … 1315 2022-09-27 21:11:56
# 4 Unknown Sumer … images… Akkadi… "htt… 160 The … -1700 2022-09-27 21:11:56
# 5 Unknown Achaem… images… Hebrew "htt… 176 The … -600 2022-09-27 21:11:56
# 6 Unknown India/… images… Arabic "htt… 288 One … 1200 2022-09-27 21:11:56
# 7 Unknown Iceland images… Old No… "htt… 384 Njál… 1350 2022-09-27 21:11:56
# 8 Jane Aus… United… images… English "htt… 226 Prid… 1813 2022-09-27 21:11:56
# 9 Honoré d… France images… French "htt… 443 Le P… 1835 2022-09-27 21:11:56
# 10 Samuel B… Republ… images… French… "htt… 256 Moll… 1952 2022-09-27 21:11:56
# … with 90 more rows, 1 more variable: month <chr>, and abbreviated variable
# names ¹​imageLink, ²​language
# ℹ Use `print(n = ...)` to see more rows, and `colnames()` to see all variable names

Realizar análise estatística em um DataFrame​

O senhor pode usar o site Sparklyr junto com o dplyr para análises estatísticas.

Por exemplo, crie um site DataFrame para executar estatísticas. Para isso, execute o código a seguir em uma célula do Notebook para usar sparklyr::sdf_copy_to e gravar o conteúdo de iris dataset que está incorporado no R em um DataFrame chamado iris. Use sparklyr::sdf_collect para imprimir as 10 primeiras linhas da tabela temporária pelo endereço default:

R
irisDF <- sdf_copy_to(
sc = sc,
x = iris,
name = "iris",
overwrite = TRUE
)

sdf_collect(irisDF, "row-wise")

# A tibble: 150 × 5
# Sepal_Length Sepal_Width Petal_Length Petal_Width Species
# <dbl> <dbl> <dbl> <dbl> <chr>
# 1 5.1 3.5 1.4 0.2 setosa
# 2 4.9 3 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 4 4.6 3.1 1.5 0.2 setosa
# 5 5 3.6 1.4 0.2 setosa
# 6 5.4 3.9 1.7 0.4 setosa
# 7 4.6 3.4 1.4 0.3 setosa
# 8 5 3.4 1.5 0.2 setosa
# 9 4.4 2.9 1.4 0.2 setosa
# 10 4.9 3.1 1.5 0.1 setosa
# … with 140 more rows
# ℹ Use `print(n = ...)` to see more rows

Agora use dplyr::group_by para agrupar linhas pela coluna Species. Use dplyr::summarize junto com dplyr::percentile_approx para calcular estatísticas resumidas pelos quantis 25, 50, 75 e 100 da coluna Sepal_Length até Species. Use sparklyr::collect para imprimir os resultados:

nota

dplyr::summarize aceita apenas argumentos que estejam em conformidade com Hive as funções integradas (também conhecidas como UDFs) e funções agregadas integradas (também conhecidas como)UDAFs do site. Para obter informações gerais, consulte Hive Functions. Para obter informações sobre percentile_approx, consulte integrada Aggregate Functions (UDAF).

R
quantileDF <- irisDF %>%
group_by(Species) %>%
summarize(
quantile_25th = percentile_approx(
Sepal_Length,
0.25
),
quantile_50th = percentile_approx(
Sepal_Length,
0.50
),
quantile_75th = percentile_approx(
Sepal_Length,
0.75
),
quantile_100th = percentile_approx(
Sepal_Length,
1.0
)
)

collect(quantileDF)

# A tibble: 3 × 5
# Species quantile_25th quantile_50th quantile_75th quantile_100th
# <chr> <dbl> <dbl> <dbl> <dbl>
# 1 virginica 6.2 6.5 6.9 7.9
# 2 versicolor 5.6 5.9 6.3 7
# 3 setosa 4.8 5 5.2 5.8

Resultados semelhantes podem ser calculados, por exemplo, usando sparklyr::sdf_quantile:

R
print(sdf_quantile(
x = irisDF %>%
filter(Species == "virginica"),
column = "Sepal_Length",
probabilities = c(0.25, 0.5, 0.75, 1.0)
))

# 25% 50% 75% 100%
# 6.2 6.5 6.9 7.9