Arbeta med DataFrames och tabeller i R
Viktig
SparkR i Databricks är inaktuell i Databricks Runtime 16.0 och senare. Databricks rekommenderar att du använder sparklyr i stället.
I den här artikeln beskrivs hur du använder R-paket som SparkR, sparklyroch dplyr för att arbeta med R data.frame
s, Spark DataFramesoch minnesinterna tabeller.
Observera att när du arbetar med SparkR, sparklyr och dplyr kan du upptäcka att du kan slutföra en viss åtgärd med alla dessa paket, och du kan använda det paket som du är mest bekväm med. Om du till exempel vill köra en fråga kan du anropa funktioner som SparkR::sql
, sparklyr::sdf_sql
och dplyr::select
. Vid andra tillfällen kanske du kan slutföra en åtgärd med bara ett eller två av dessa paket, och den åtgärd du väljer beror på ditt användningsscenario. Till exempel skiljer sig sättet du anropar sparklyr::sdf_quantile
något från hur du anropar dplyr::percentile_approx
, även om båda funktionerna beräknar kvantantiklar.
Du kan använda SQL som en brygga mellan SparkR och sparklyr. Du kan till exempel använda SparkR::sql
för att fråga efter tabeller som du skapar med sparklyr. Du kan använda sparklyr::sdf_sql
för att fråga efter tabeller som du skapar med SparkR. Och dplyr
kod översätts alltid till SQL i minnet innan den körs. Se även API-samverkan och SQL Translation.
Läs in SparkR, sparklyr och dplyr
SparkR-, sparklyr- och dplyr-paketen ingår i Databricks Runtime som är installerat på Azure Databricks kluster. Därför behöver du inte anropa den vanliga install.package
innan du kan börja anropa dessa paket. Du måste dock fortfarande läsa in dessa paket med library
först. Från en R notebook- i en Azure Databricks-arbetsyta kör du till exempel följande kod i en notebook-cell för att läsa in SparkR, sparklyr och dplyr:
library(SparkR)
library(sparklyr)
library(dplyr)
Ansluta sparklyr till ett kluster
När du har läst in sparklyr måste du anropa sparklyr::spark_connect
för att ansluta till klustret och ange databricks
som anslutningsmetod. Kör till exempel följande kod i en notebook-cell för att ansluta till klustret som är värd för notebook-filen:
sc <- spark_connect(method = "databricks")
Däremot upprättar en Azure Databricks-notebook redan en SparkSession
i klustret för att använda med SparkR, så du behöver inte köra SparkR::sparkR.session
innan du kan börja köra SparkR.
Ladda upp en JSON-datafil till din arbetsyta
Många av kodexemplen i den här artikeln baseras på data på en specifik plats på din Azure Databricks-arbetsyta, med specifika kolumnnamn och datatyper. Data för det här kodexemplet kommer från en JSON-fil med namnet book.json
inifrån GitHub. Så här hämtar du den här filen och laddar upp den till din arbetsyta:
- Gå till den books.json filen på GitHub och använd en textredigerare för att kopiera innehållet till en fil med namnet
books.json
någonstans på den lokala datorn. - I sidofältet för Azure Databricks-arbetsytan klickar du på Catalog.
- Klicka på Skapa tabell.
- På fliken Ladda upp fil släpper du filen
books.json
från den lokala datorn till rutan Släpp filer för att ladda upp. Eller välj klicka för att bläddra, och bläddra tillbooks.json
-filen från din lokala dator.
Som standard laddar Azure Databricks upp din lokala books.json
-fil till DBFS- plats på arbetsytan med sökvägen /FileStore/tables/books.json
.
Klicka inte på Skapa tabell med användargränssnittet eller Skapa tabell i notebooken. Kodexemplen i den här artikeln använder data i den uppladdade books.json
-filen på den här DBFS-platsen.
Läs JSON-data till en DataFrame
Använd sparklyr::spark_read_json
för att läsa den uppladdade JSON-filen till en DataFrame, ange anslutningen, sökvägen till JSON-filen och ett namn för den interna tabellrepresentationen av data. I det här exemplet måste du ange att filen book.json
innehåller flera rader. Det är valfritt att ange kolumnernas schema här. Annars härleder sparklyr kolumnernas schema som standard. Kör till exempel följande kod i en notebook-cell för att läsa den uppladdade JSON-filens data till en DataFrame med namnet 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"
)
)
Skriv ut de första raderna i en DataFrame
Du kan använda SparkR::head
, SparkR::show
eller sparklyr::collect
för att skriva ut de första raderna i en DataFrame. Som standard skriver head
ut de första sex raderna som standard.
show
och collect
skriva ut de första 10 raderna. Kör till exempel följande kod i en notebook-cell för att skriva ut de första raderna i DataFrame med namnet jsonDF
:
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
Utför SQL-frågor och skriv till och läs från en tabell
Du kan använda dplyr-funktioner för att köra SQL-frågor på en DataFrame. Kör till exempel följande kod i en notebook-cell för att använda dplyr::group_by
och dployr::count
för att hämta antal av författare från DataFrame med namnet jsonDF
. Använd dplyr::arrange
och dplyr::desc
för att sortera resultatet i fallande ordning efter antal. Skriv sedan ut de första 10 raderna som standard.
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
Du kan sedan använda sparklyr::spark_write_table
för att skriva resultatet till en tabell i Azure Databricks. Kör till exempel följande kod i en notebook-cell för att köra frågan igen och skriv sedan resultatet till en tabell med namnet json_books_agg
:
group_by(jsonDF, author) %>%
count() %>%
arrange(desc(n)) %>%
spark_write_table(
name = "json_books_agg",
mode = "overwrite"
)
För att kontrollera att tabellen har skapats kan du sedan använda sparklyr::sdf_sql
tillsammans med SparkR::showDF
för att visa tabellens data. Kör till exempel följande kod i en notebook-cell för att fråga tabellen till en DataFrame och använd sedan sparklyr::collect
för att skriva ut de första 10 raderna i DataFrame som standard:
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
Du kan också använda sparklyr::spark_read_table
för att göra något liknande. Kör till exempel följande kod i en notebook-cell för att göra frågor mot den tidigare nämnda DataFrame jsonDF
och omvandla den till en ny DataFrame. Använd sedan sparklyr::collect
för att som standard skriva ut de första 10 raderna av DataFrame:
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
Lägga till kolumner och beräkningskolumnvärden i en DataFrame
Du kan använda dplyr-funktioner för att lägga till kolumner i DataFrames och för att beräkna kolumners värden.
Kör till exempel följande kod i en notebook-cell för att hämta innehållet i dataramen med namnet jsonDF
. Använd dplyr::mutate
om du vill lägga till en kolumn med namnet today
och fylla den nya kolumnen med den aktuella tidsstämpeln. Skriv sedan innehållet till en ny DataFrame med namnet withDate
och använd dplyr::collect
för att skriva ut den nya DataFrames första 10 rader som standard.
Note
dplyr::mutate
accepterar endast argument som överensstämmer med Hive:s inbyggda funktioner (även kallade UDF:er) och inbyggda aggregerade funktioner (även kallade UDAF:er). Allmän information finns i Hive Functions. Information om datumrelaterade funktioner i det här avsnittet finns i Date Functions.
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
Använd nu dplyr::mutate
för att lägga till ytterligare två kolumner i innehållet i withDate
DataFrame. De nya kolumnerna month
och year
innehåller den numeriska månaden och året från kolumnen today
. Skriv sedan innehållet till en ny DataFrame med namnet withMMyyyy
och använd dplyr::select
tillsammans med dplyr::collect
för att skriva ut kolumnerna author
, title
, month
och year
i den nya DataFrame:s tio första rader som standard:
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
Använd nu dplyr::mutate
för att lägga till ytterligare två kolumner i innehållet i withMMyyyy
DataFrame. De nya formatted_date
kolumnerna innehåller den yyyy-MM-dd
delen från kolumnen today
, medan den nya day
-kolumnen innehåller den numeriska dagen från den nya formatted_date
kolumnen. Skriv sedan innehållet till en ny DataFrame med namnet withUnixTimestamp
och använd dplyr::select
tillsammans med dplyr::collect
för att skriva ut kolumnerna title
, formatted_date
och day
i den nya DataFrame:s tio första rader som standard:
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
Skapa en tillfällig vy
Du kan skapa namngivna tillfälliga vyer i minnet som baseras på befintliga DataFrames. Kör till exempel följande kod i en notebook-cell för att använda SparkR::createOrReplaceTempView
för att hämta innehållet i föregående DataFrame med namnet jsonTable
och göra en tillfällig vy av den med namnet timestampTable
. Använd sedan sparklyr::spark_read_table
för att läsa innehållet i den temporära vyn. Använd sparklyr::collect
för att skriva ut de första 10 raderna i den temporära tabellen som standard:
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
Utföra statistisk analys på en DataFrame
Du kan använda sparklyr tillsammans med dplyr för statistiska analyser.
Skapa till exempel en DataFrame att köra statistik på. Det gör du genom att köra följande kod i en notebook-cell för att använda sparklyr::sdf_copy_to
för att skriva innehållet i den iris
datauppsättning som är inbyggd i R till en dataram med namnet iris
. Använd sparklyr::sdf_collect
för att skriva ut de första 10 raderna i den temporära tabellen som standard:
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
Använd nu dplyr::group_by
för att gruppera rader efter kolumnen Species
. Använd dplyr::summarize
tillsammans med dplyr::percentile_approx
för att beräkna sammanfattningsstatistik efter den 25:e, 50:e, 75:e och 100:e kvantilen av Sepal_Length
-kolumnen efter Species
. Använd sparklyr::collect
och skriv ut resultaten:
Note
dplyr::summarize
accepterar endast argument som överensstämmer med Hive:s inbyggda funktioner (även kallade UDF:er) och inbyggda aggregerade funktioner (även kallade UDAF:er). Allmän information finns i Hive Functions. Information om percentile_approx
finns i Inbyggda aggregerade funktioner (UDAF).
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
Liknande resultat kan till exempel beräknas med hjälp av 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