Werken met DataFrames en tabellen in R
In dit artikel wordt beschreven hoe u R-pakketten zoals SparkR, sparklyr en dplyr gebruikt om te werken met R data.frame
s, Spark DataFrames en tabellen in het geheugen.
Houd er rekening mee dat wanneer u met SparkR, sparklyr en dplyr werkt, u mogelijk een bepaalde bewerking met al deze pakketten kunt voltooien en u het pakket kunt gebruiken waarmee u het meest vertrouwd bent. Als u bijvoorbeeld een query wilt uitvoeren, kunt u functies aanroepen zoals SparkR::sql
, sparklyr::sdf_sql
en dplyr::select
. Op andere momenten kunt u mogelijk een bewerking met slechts één of twee van deze pakketten voltooien en de bewerking die u kiest, is afhankelijk van uw gebruiksscenario. De manier waarop u aanroept sparklyr::sdf_quantile
, verschilt bijvoorbeeld iets van de manier waarop u aanroept dplyr::percentile_approx
, ook al werken beide functies kwantielen.
U kunt SQL gebruiken als een brug tussen SparkR en sparklyr. U kunt bijvoorbeeld query's uitvoeren SparkR::sql
op tabellen die u met sparklyr maakt. U kunt sparklyr::sdf_sql
query's uitvoeren op tabellen die u met SparkR maakt. Code dplyr
wordt altijd vertaald naar SQL in het geheugen voordat deze wordt uitgevoerd. Zie ook API-interoperabiliteit en SQL-vertaling.
SparkR, sparklyr en dplyr laden
De SparkR-, sparklyr- en dplyr-pakketten zijn opgenomen in de Databricks Runtime die is geïnstalleerd op Azure Databricks-clusters. Daarom hoeft u niet de gebruikelijke install.package
aan te roepen voordat u kunt beginnen met het aanroepen van deze pakketten. U moet deze pakketten library
echter wel eerst laden. Voer bijvoorbeeld vanuit een R-notebook in een Azure Databricks-werkruimte de volgende code uit in een notebookcel om SparkR, sparklyr en dplyr te laden:
library(SparkR)
library(sparklyr)
library(dplyr)
Verbinding maken sparklyr naar een cluster
Nadat u sparklyr hebt geladen, moet u aanroepen sparklyr::spark_connect
om verbinding te maken met het cluster, waarbij u de databricks
verbindingsmethode opgeeft. Voer bijvoorbeeld de volgende code uit in een notebookcel om verbinding te maken met het cluster dat als host fungeert voor het notebook:
sc <- spark_connect(method = "databricks")
Een Azure Databricks-notebook brengt daarentegen al een SparkSession
cluster op voor gebruik met SparkR, dus u hoeft niet aan te roepen SparkR::sparkR.session
voordat u SparkR kunt aanroepen.
Een JSON-gegevensbestand uploaden naar uw werkruimte
Veel van de codevoorbeelden in dit artikel zijn gebaseerd op gegevens op een specifieke locatie in uw Azure Databricks-werkruimte, met specifieke kolomnamen en gegevenstypen. De gegevens voor dit codevoorbeeld zijn afkomstig uit een JSON-bestand met de naam book.json
vanuit GitHub. Ga als volgt te werk om dit bestand op te halen en te uploaden naar uw werkruimte:
- Ga naar het bestand books.json op GitHub en gebruik een teksteditor om de inhoud ervan te kopiëren naar een bestand met de naam
books.json
ergens op uw lokale computer. - Klik in de zijbalk van uw Azure Databricks-werkruimte op Catalogus.
- Klik op Tabel maken.
- Zet op het tabblad Bestand uploaden het
books.json
bestand van uw lokale computer neer op het vak Bestanden neerzetten om te uploaden . Of klik om te bladeren en blader naar hetbooks.json
bestand vanaf uw lokale computer.
Standaard uploadt Azure Databricks uw lokale books.json
bestand naar de DBFS-locatie in uw werkruimte met het pad /FileStore/tables/books.json
.
Klik niet op Tabel maken met gebruikersinterface of Tabel maken in Notebook. De codevoorbeelden in dit artikel gebruiken de gegevens in het geüploade books.json
bestand op deze DBFS-locatie.
De JSON-gegevens lezen in een DataFrame
Gebruik sparklyr::spark_read_json
dit bestand om het geüploade JSON-bestand te lezen in een DataFrame, waarbij de verbinding, het pad naar het JSON-bestand en een naam voor de interne tabelweergave van de gegevens worden opgegeven. In dit voorbeeld moet u opgeven dat het book.json
bestand meerdere regels bevat. Het schema van de kolommen is hier optioneel. Anders wordt het schema van de kolommen standaard afgeleid door sparklyr. Voer bijvoorbeeld de volgende code uit in een notebookcel om de gegevens van het geüploade JSON-bestand te lezen in een DataFrame met de naam jsonDF
:
jsonDF <- spark_read_json(
sc = sc,
name = "jsonTable",
path = "/FileStore/tables/books.json",
options = list("multiLine" = TRUE),
columns = c(
author = "character",
country = "character",
imageLink = "character",
language = "character",
link = "character",
pages = "integer",
title = "character",
year = "integer"
)
)
De eerste paar rijen van een DataFrame afdrukken
U kunt de eerste rijen van een DataFrame gebruiken SparkR::head
, SparkR::show
of sparklyr::collect
afdrukken. head
Standaard worden de eerste zes rijen standaard afgedrukt. show
en collect
druk de eerste 10 rijen af. Voer bijvoorbeeld de volgende code uit in een notebookcel om de eerste rijen van het DataFrame met de naam jsonDF
af te drukken:
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
SQL-query's uitvoeren en schrijven naar en lezen vanuit een tabel
U kunt dplyr-functies gebruiken om SQL-query's uit te voeren op een DataFrame. Voer bijvoorbeeld de volgende code uit in een notebookcel om te gebruiken dplyr::group_by
en dployr::count
om tellingen op te halen op basis van de auteur van het DataFrame met de naam jsonDF
. Gebruik dplyr::arrange
en dplyr::desc
sorteer het resultaat in aflopende volgorde op aantallen. Druk vervolgens de eerste 10 rijen standaard af.
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
Vervolgens kunt sparklyr::spark_write_table
u het resultaat naar een tabel in Azure Databricks schrijven. Voer bijvoorbeeld de volgende code uit in een notebookcel om de query opnieuw uit te voeren en schrijf vervolgens het resultaat naar een tabel met de naam json_books_agg
:
group_by(jsonDF, author) %>%
count() %>%
arrange(desc(n)) %>%
spark_write_table(
name = "json_books_agg",
mode = "overwrite"
)
Als u wilt controleren of de tabel is gemaakt, kunt u deze samen SparkR::showDF
gebruiken sparklyr::sdf_sql
om de gegevens van de tabel weer te geven. Voer bijvoorbeeld de volgende code uit in een notebookcel om een query uit te voeren op de tabel in een DataFrame en gebruik sparklyr::collect
vervolgens om de eerste 10 rijen van het DataFrame standaard af te drukken:
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
U kunt ook iets soortgelijks doen sparklyr::spark_read_table
. Voer bijvoorbeeld de volgende code uit in een notebookcel om een query uit te voeren op het voorgaande DataFrame met de naam jsonDF
in een DataFrame en gebruik sparklyr::collect
deze vervolgens om de eerste tien rijen van het DataFrame standaard af te drukken:
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
Kolommen en berekende kolomwaarden toevoegen in een DataFrame
U kunt dplyr-functies gebruiken om kolommen toe te voegen aan DataFrames en om de waarden van kolommen te berekenen.
Voer bijvoorbeeld de volgende code uit in een notebookcel om de inhoud van het DataFrame met de naam jsonDF
op te halen. Hiermee dplyr::mutate
voegt u een kolom met de naam today
toe en vult u deze nieuwe kolom met de huidige tijdstempel. Schrijf deze inhoud vervolgens naar een nieuw DataFrame met de naam withDate
en gebruik dplyr::collect
deze om de eerste 10 rijen van het nieuwe DataFrame standaard af te drukken.
Notitie
dplyr::mutate
accepteert alleen argumenten die voldoen aan de ingebouwde functies van Hive (ook wel UDF's genoemd) en ingebouwde statistische functies (ook wel UDAF's genoemd). Zie Hive-functies voor algemene informatie. Zie Datumfuncties voor informatie over de datumgerelateerde functies in deze sectie.
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
dplyr::mutate
Gebruik nu om nog twee kolommen toe te voegen aan de inhoud van het withDate
DataFrame. De nieuwe month
kolommen year
bevatten de numerieke maand en het jaar uit de today
kolom. Schrijf deze inhoud vervolgens naar een nieuw DataFrame met de naam withMMyyyy
en gebruik dplyr::select
deze samen om dplyr::collect
de author
, title
month
en year
kolommen van de eerste tien rijen van het nieuwe DataFrame standaard af te drukken:
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
dplyr::mutate
Gebruik nu om nog twee kolommen toe te voegen aan de inhoud van het withMMyyyy
DataFrame. De nieuwe formatted_date
kolommen bevatten het yyyy-MM-dd
gedeelte van de today
kolom, terwijl de nieuwe day
kolom de numerieke dag van de nieuwe formatted_date
kolom bevat. Schrijf deze inhoud vervolgens naar een nieuw DataFrame met de naam withUnixTimestamp
en gebruik dplyr::select
deze samen om dplyr::collect
de title
, formatted_date
en day
kolommen van de eerste tien rijen van het nieuwe DataFrame standaard af te drukken:
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
Een tijdelijke weergave maken
U kunt benoemde tijdelijke weergaven maken in het geheugen die zijn gebaseerd op bestaande DataFrames. Voer bijvoorbeeld de volgende code uit in een notebookcel om de inhoud van het voorgaande DataFrame met de naam jsonTable
timestampTable
op te SparkR::createOrReplaceTempView
halen en er een tijdelijke weergave van te maken. Gebruik vervolgens sparklyr::spark_read_table
om de inhoud van de tijdelijke weergave te lezen. Gebruik sparklyr::collect
deze functie om standaard de eerste tien rijen van de tijdelijke tabel af te drukken:
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
Statistische analyse uitvoeren op een DataFrame
U kunt sparklyr samen met dplyr gebruiken voor statistische analyses.
Maak bijvoorbeeld een DataFrame waarop statistieken moeten worden uitgevoerd. Voer hiervoor de volgende code uit in een notebookcel om sparklyr::sdf_copy_to
de inhoud te schrijven van de iris
gegevensset die is ingebouwd in R naar een DataFrame met de naam iris
. Gebruik sparklyr::sdf_collect
deze functie om standaard de eerste tien rijen van de tijdelijke tabel af te drukken:
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
dplyr::group_by
Gebruik nu om rijen op de Species
kolom te groeperen. Gebruik dplyr::summarize
samen met dplyr::percentile_approx
het berekenen van samenvattingsstatistieken op de 25e, 50e, 75e en 100e kwantielen van de Sepal_Length
kolom per Species
. Gebruik sparklyr::collect
een afdruk van de resultaten:
Notitie
dplyr::summarize
accepteert alleen argumenten die voldoen aan de ingebouwde functies van Hive (ook wel UDF's genoemd) en ingebouwde statistische functies (ook wel UDAF's genoemd). Zie Hive-functies voor algemene informatie. Zie Ingebouwde statistische functies (UDAF) voor meer informatie.percentile_approx
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
Vergelijkbare resultaten kunnen bijvoorbeeld worden berekend met behulp van sparklyr::sdf_quantile
:
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