Delen via


Werken met DataFrames en tabellen in R

Belangrijk

SparkR in Databricks is verouderd verklaard in Databricks Runtime 16.0 en hoger. Databricks raadt aan om in plaats daarvan sparklyr- te gebruiken.

In dit artikel wordt beschreven hoe u R-pakketten zoals SparkR-, sparklyr-en dplyr- kunt gebruiken om te werken met R data.frames, Spark DataFramesen 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 sparklyr::sdf_quantile aanroept, verschilt bijvoorbeeld enigszins van de manier waarop u dplyr::percentile_approxaanroept, zelfs als beide functies kwantielen berekenen.

U kunt SQL gebruiken als een brug tussen SparkR en sparklyr. U kunt bijvoorbeeld SparkR::sql gebruiken om query's uit te voeren op tabellen die u met sparklyr maakt. U kunt sparklyr::sdf_sql gebruiken om query's uit te voeren op tabellen die u met SparkR maakt. En dplyr code wordt altijd vertaald naar SQL in het geheugen voordat deze wordt uitgevoerd. Zie ook API-interoperabiliteit en SQL Translation.

Het laden van SparkR, sparklyr en dplyr

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 deze pakketten kunt aanroepen. U moet deze pakketten echter nog steeds laden met library eerst. 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)

Sparklyr verbinden met een cluster

Nadat u sparklyr hebt geladen, moet u sparklyr::spark_connect aanroepen 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")

In een Azure Databricks-notebook wordt daarentegen al een SparkSession op het cluster gemaakt voor gebruik met SparkR. U hoeft dus geen SparkR::sparkR.session aan te roepen 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 books.json-bestand 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 Catalog.
  3. Klik op Tabel maken.
  4. Zet op het tabblad Bestand Uploaden het books.json bestand van uw lokale computer in het vak Bestanden slepen om te uploaden neer. Of selecteer , klik omte openen, en zoek het books.json-bestand op uw lokale computer op.

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 UI 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 om het geüploade JSON-bestand te lezen in een DataFrame, waarbij u de verbinding, het pad naar het JSON-bestand en een naam opgeeft voor de interne tabelweergave van de gegevens. 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 SparkR::head, SparkR::showof sparklyr::collect gebruiken om de eerste rijen van een DataFrame af te drukken. Standaard print head de eerste zes rijen. show en collect de eerste 10 rijen afdrukken. 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 dplyr::group_by en dployr::count te gebruiken om tellingen per auteur te verkrijgen uit het DataFrame met de naam jsonDF. Gebruik dplyr::arrange en dplyr::desc om het resultaat in aflopende volgorde te sorteren 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 u sparklyr::spark_write_table gebruiken om het resultaat naar een tabel in Azure Databricks te 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 sparklyr::sdf_sql samen met SparkR::showDF gebruiken 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 vervolgens sparklyr::collect 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 sparklyr::spark_read_table gebruiken om iets vergelijkbaars te doen. 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 vervolgens sparklyr::collect 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. Gebruik dplyr::mutate om een kolom met de naam todaytoe te voegen en deze nieuwe kolom te vullen met de huidige tijdstempel. Schrijf deze inhoud vervolgens naar een nieuw DataFrame met de naam withDate en gebruik dplyr::collect 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 Functionsvoor algemene informatie. Zie Datumfunctiesvoor meer 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

Gebruik nu dplyr::mutate om nog twee kolommen toe te voegen aan de inhoud van het withDate DataFrame. De nieuwe kolommen month en year bevatten de numerieke maand en het jaar uit de kolom today. Schrijf deze inhoud vervolgens naar een nieuw DataFrame met de naam withMMyyyyen gebruik dplyr::select samen met dplyr::collect om 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

Gebruik nu dplyr::mutate 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 uit de kolom today, 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 samen met dplyr::collect om 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 SparkR::createOrReplaceTempView te gebruiken om de inhoud van het voorgaande DataFrame met de naam jsonTable op te halen en er een tijdelijke weergave van te maken met de naam timestampTable. Gebruik vervolgens sparklyr::spark_read_table om de inhoud van de tijdelijke weergave te lezen. Gebruik sparklyr::collect om de eerste tien rijen van de tijdelijke tabel standaard 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 te gebruiken om de inhoud van de iris gegevensset te schrijven die is ingebouwd in R naar een DataFrame met de naam iris. Gebruik sparklyr::sdf_collect om de eerste tien rijen van de tijdelijke tabel standaard 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

Gebruik nu dplyr::group_by om rijen te groeperen op de Species kolom. Gebruik dplyr::summarize samen met dplyr::percentile_approx om samenvattingsstatistieken te berekenen op basis van de 25e, 50e, 75e en 100e kwantielen van de kolom Sepal_Length per Species. Gebruik sparklyr::collect om de resultaten af te drukken:

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 Functionsvoor algemene informatie. Raadpleeg percentile_approxvoor meer informatie over .

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