Delen via


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.frames, 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_sqlen 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:

  1. 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.
  2. Klik in de zijbalk van uw Azure Databricks-werkruimte op Catalogus.
  3. Klik op Tabel maken.
  4. 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 het books.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"
  )
)

U kunt de eerste rijen van een DataFrame gebruiken SparkR::head, SparkR::showof 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 jsonDFaf 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 jsonDFop te halen. Hiermee dplyr::mutate voegt u een kolom met de naam todaytoe 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 withMMyyyyen gebruik dplyr::select deze samen om dplyr::collect de author, titlemonth 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 withUnixTimestampen gebruik dplyr::select deze samen om dplyr::collect de title, formatted_dateen 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 jsonTabletimestampTableop 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