Praca z ramkami danych i tabelami w języku R
W tym artykule opisano sposób używania pakietów języka R, takich jak SparkR, sparklyr i dplyr do pracy z tabelami R data.frame
s, Spark DataFrames i in-memory.
Pamiętaj, że podczas pracy z usługą SparkR, sparklyr i dplyr możesz stwierdzić, że możesz ukończyć określoną operację ze wszystkimi tymi pakietami i użyć pakietu, z którym najlepiej się korzystasz. Aby na przykład uruchomić zapytanie, można wywołać funkcje, takie jak SparkR::sql
, sparklyr::sdf_sql
i dplyr::select
. Czasami możesz wykonać operację tylko z jednym lub dwoma z tych pakietów, a wybrana operacja zależy od scenariusza użycia. Na przykład sposób wywoływania sparklyr::sdf_quantile
różni się nieco od sposobu wywoływania dplyr::percentile_approx
metody , mimo że oba funkcje pełnią kwantyle calcuate.
Możesz użyć języka SQL jako mostka między platformą SparkR i interfejsem sparklyr. Na przykład możesz użyć SparkR::sql
polecenia , aby wykonywać zapytania dotyczące tabel tworzonych za pomocą interfejsu sparklyr. Do wykonywania zapytań dotyczących tabel tworzonych za pomocą aparatu SparkR można użyć sparklyr::sdf_sql
polecenia . Kod dplyr
jest zawsze tłumaczony na język SQL w pamięci przed jego uruchomieniem. Zobacz też Współdziałanie interfejsu API i Tłumaczenie SQL.
Ładowanie sparkR, sparklyr i dplyr
Pakiety SparkR, sparklyr i dplyr są zawarte w środowisku Databricks Runtime zainstalowanym w klastrach usługi Azure Databricks. W związku z tym nie trzeba wywoływać zwykłych install.package
pakietów przed rozpoczęciem wywoływania tych pakietów. Jednak nadal należy załadować te pakiety za pomocą library
polecenia . Na przykład z poziomu notesu języka R w obszarze roboczym usługi Azure Databricks uruchom następujący kod w komórce notesu, aby załadować usługę SparkR, sparklyr i dplyr:
library(SparkR)
library(sparklyr)
library(dplyr)
Połączenie sparklyr do klastra
Po załadowaniu narzędzia sparklyr należy wywołać metodę sparklyr::spark_connect
, aby nawiązać połączenie z klastrem, określając metodę databricks
połączenia. Na przykład uruchom następujący kod w komórce notesu, aby nawiązać połączenie z klastrem hostujący notes:
sc <- spark_connect(method = "databricks")
Z kolei notes usługi Azure Databricks już ustanawia SparkSession
klaster do użycia z usługą SparkR, więc nie musisz wywoływać SparkR::sparkR.session
przed rozpoczęciem wywoływania aparatu SparkR.
Przekazywanie pliku danych JSON do obszaru roboczego
Wiele przykładów kodu w tym artykule jest opartych na danych w określonej lokalizacji w obszarze roboczym usługi Azure Databricks z określonymi nazwami kolumn i typami danych. Dane dla tego przykładu kodu pochodzą z pliku JSON o nazwie book.json
z usługi GitHub. Aby pobrać ten plik i przekazać go do obszaru roboczego:
- Przejdź do pliku books.json w usłudze GitHub i użyj edytora tekstów, aby skopiować jego zawartość do pliku o nazwie
books.json
gdzieś na komputerze lokalnym. - Na pasku bocznym obszaru roboczego usługi Azure Databricks kliknij pozycję Wykaz.
- Kliknij pozycję Utwórz tabelę.
- Na karcie Przekaż plik upuść plik z komputera lokalnego do pola Upuść
books.json
pliki, aby przekazać. Możesz też wybrać przycisk przeglądania i przejść do pliku z komputera lokalnegobooks.json
.
Domyślnie usługa Azure Databricks przekazuje plik lokalny books.json
do lokalizacji DBFS w obszarze roboczym ze ścieżką /FileStore/tables/books.json
.
Nie klikaj pozycji Utwórz tabelę za pomocą interfejsu użytkownika lub Utwórz tabelę w notesie. Przykłady kodu w tym artykule używają danych w przekazanym books.json
pliku w tej lokalizacji systemu plików DBFS.
Odczytywanie danych JSON do ramki danych
Służy sparklyr::spark_read_json
do odczytywania przekazanego pliku JSON do ramki danych, określania połączenia, ścieżki do pliku JSON i nazwy wewnętrznej reprezentacji danych w tabeli wewnętrznej. W tym przykładzie należy określić, że book.json
plik zawiera wiele wierszy. Określenie schematu kolumn jest tutaj opcjonalne. W przeciwnym razie interfejs sparklyr domyślnie wywnioskuje schemat kolumn. Na przykład uruchom następujący kod w komórce notesu, aby odczytać przekazane dane pliku JSON do ramki danych o nazwie 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"
)
)
Drukowanie pierwszych kilku wierszy ramki danych
Możesz użyć SparkR::head
metody , SparkR::show
lub sparklyr::collect
, aby wydrukować pierwsze wiersze ramki danych. Domyślnie drukuje pierwsze sześć wierszy domyślnie head
. show
i collect
wyświetl pierwsze 10 wierszy. Na przykład uruchom następujący kod w komórce notesu, aby wydrukować pierwsze wiersze ramki danych o nazwie 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
Uruchamianie zapytań SQL i zapisywanie w tabeli i odczytywanie ich z tabeli
Za pomocą funkcji dplyr można uruchamiać zapytania SQL w ramce danych. Na przykład uruchom następujący kod w komórce notesu, aby użyć dplyr::group_by
polecenia i dployr::count
pobrać liczby autorów z ramki danych o nazwie jsonDF
. Użyj funkcji dplyr::arrange
i dplyr::desc
, aby posortować wynik w kolejności malejącej według liczb. Następnie domyślnie wydrukuj pierwsze 10 wierszy.
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
Następnie możesz użyć sparklyr::spark_write_table
polecenia , aby zapisać wynik w tabeli w usłudze Azure Databricks. Na przykład uruchom następujący kod w komórce notesu, aby ponownie uruchomić zapytanie, a następnie zapisz wynik w tabeli o nazwie json_books_agg
:
group_by(jsonDF, author) %>%
count() %>%
arrange(desc(n)) %>%
spark_write_table(
name = "json_books_agg",
mode = "overwrite"
)
Aby sprawdzić, czy tabela została utworzona, możesz użyć polecenia sparklyr::sdf_sql
wraz z poleceniem SparkR::showDF
, aby wyświetlić dane tabeli. Na przykład uruchom następujący kod w komórce notesu, aby wykonać zapytanie względem tabeli w ramce danych, a następnie użyj polecenia sparklyr::collect
, aby wydrukować pierwsze 10 wierszy ramki danych domyślnie:
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
Możesz również użyć sparklyr::spark_read_table
polecenia , aby zrobić coś podobnego. Na przykład uruchom następujący kod w komórce notesu, aby wykonać zapytanie względem poprzedniej ramki danych o nazwie jsonDF
w ramce danych, a następnie użyj polecenia sparklyr::collect
, aby wydrukować pierwsze 10 wierszy ramki danych domyślnie:
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
Dodawanie kolumn i wartości kolumn obliczeniowych w ramce danych
Za pomocą funkcji dplyr można dodawać kolumny do ramek danych i wartości kolumn obliczeniowych.
Na przykład uruchom następujący kod w komórce notesu, aby pobrać zawartość ramki danych o nazwie jsonDF
. Użyj dplyr::mutate
polecenia , aby dodać kolumnę o nazwie today
i wypełnić tę nową kolumnę bieżącym znacznikiem czasu. Następnie zapisz te elementy w nowej ramce danych o nazwie withDate
i użyj polecenia dplyr::collect
, aby wydrukować domyślnie pierwsze 10 wierszy nowej ramki danych.
Uwaga
dplyr::mutate
Akceptuje tylko argumenty zgodne z wbudowanymi funkcjami programu Hive (znanymi również jako funkcje zdefiniowane przez użytkownika) i wbudowanymi funkcjami agregacji (znanymi również jako FUNKCJE UDAFs). Aby uzyskać ogólne informacje, zobacz Hive Functions. Aby uzyskać informacje o funkcjach związanych z datą w tej sekcji, zobacz Funkcje daty.
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
Teraz użyj polecenia dplyr::mutate
, aby dodać dwie kolejne kolumny do zawartości withDate
ramki danych. Nowe month
kolumny i year
zawierają numerowy miesiąc i rok z kolumny today
. Następnie zapisz te elementy w nowej ramce danych o nazwie withMMyyyy
i użyj polecenia dplyr::select
wraz z poleceniem author
month
dplyr::collect
title
, i year
kolumny pierwszych dziesięciu wierszy nowej ramki danych domyślnie:
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
Teraz użyj polecenia dplyr::mutate
, aby dodać dwie kolejne kolumny do zawartości withMMyyyy
ramki danych. Nowe formatted_date
kolumny zawierają yyyy-MM-dd
część z today
kolumny, a nowa day
kolumna zawiera dzień liczbowy z nowej formatted_date
kolumny. Następnie zapisz te elementy w nowej ramce danych o nazwie withUnixTimestamp
i użyj polecenia dplyr::select
wraz z poleceniem title
dplyr::collect
formatted_date
, i day
kolumny pierwszych dziesięciu wierszy nowej ramki danych domyślnie:
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
Tworzenie widoku tymczasowego
Możesz utworzyć nazwane widoki tymczasowe w pamięci, które są oparte na istniejących ramkach danych. Na przykład uruchom następujący kod w komórce notesu, aby użyć SparkR::createOrReplaceTempView
polecenia w celu pobrania zawartości poprzedniej ramki danych o nazwie i utworzenia tymczasowego widoku z niego o nazwie jsonTable
timestampTable
. Następnie użyj polecenia sparklyr::spark_read_table
, aby odczytać zawartość widoku tymczasowego. Użyj sparklyr::collect
polecenia , aby wydrukować pierwsze 10 wierszy tabeli tymczasowej domyślnie:
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
Przeprowadzanie analizy statystycznej na ramce danych
Do analizy statystycznej można używać interfejsu sparklyr wraz z dplyr.
Na przykład utwórz ramkę danych do uruchamiania statystyk. W tym celu uruchom następujący kod w komórce notesu, aby użyć sparklyr::sdf_copy_to
go do zapisania zawartości iris
zestawu danych wbudowanego w język R w ramce danych o nazwie iris
. Użyj sparklyr::sdf_collect
polecenia , aby wydrukować pierwsze 10 wierszy tabeli tymczasowej domyślnie:
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
Teraz użyj polecenia dplyr::group_by
, aby pogrupować wiersze według kolumny Species
. Użyj polecenia dplyr::summarize
, dplyr::percentile_approx
aby obliczyć statystyki podsumowania według 25, 50, 75 i 100 kwantyli Sepal_Length
kolumny według Species
. Użyj sparklyr::collect
wydruku wyników:
Uwaga
dplyr::summarize
Akceptuje tylko argumenty zgodne z wbudowanymi funkcjami programu Hive (znanymi również jako funkcje zdefiniowane przez użytkownika) i wbudowanymi funkcjami agregacji (znanymi również jako FUNKCJE UDAFs). Aby uzyskać ogólne informacje, zobacz Hive Functions. Aby uzyskać informacje o percentile_approx
systemie, zobacz Wbudowane funkcje agregujące (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
Podobne wyniki można obliczyć, na przykład przy użyciu polecenia 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