Bagikan melalui


Bekerja dengan DataFrame dan tabel di R

Penting

SparkR di Databricks yang tidak digunakan lagi di Databricks Runtime 16.0 ke atas. Databricks merekomendasikan menggunakan sparklyr sebagai gantinya.

Artikel ini menjelaskan cara menggunakan paket R seperti SparkR, sparklyr, dan dplyr untuk bekerja dengan tabel R data.frames, Spark DataFrames, dan dalam memori.

Perhatikan bahwa saat Anda bekerja dengan SparkR, sparklyr, dan dplyr, Anda mungkin menemukan bahwa Anda dapat menyelesaikan operasi tertentu dengan semua paket ini, dan Anda dapat menggunakan paket yang paling nyaman bagi Anda. Misalnya, untuk menjalankan kueri, Anda dapat memanggil fungsi seperti SparkR::sql, sparklyr::sdf_sql, dan dplyr::select. Di lain waktu, Anda mungkin dapat menyelesaikan operasi hanya dengan satu atau dua paket ini, dan operasi yang Anda pilih tergantung pada skenario penggunaan Anda. Misalnya, cara Anda memanggil sparklyr::sdf_quantile sedikit berbeda dari cara Anda memanggil dplyr::percentile_approx, meskipun kedua fungsi menghitung kuantil.

Anda dapat menggunakan SQL sebagai jembatan antara SparkR dan sparklyr. Misalnya, Anda bisa menggunakan SparkR::sql untuk mengkueri tabel yang Anda buat dengan sparklyr. Anda bisa menggunakan sparklyr::sdf_sql untuk mengkueri tabel yang Anda buat dengan SparkR. Dan kode dplyr selalu diterjemahkan ke SQL dalam memori sebelum dijalankan. Lihat juga interoperabilitas API dan Terjemahan SQL.

Muat SparkR, sparklyr, dan dplyr

Paket SparkR, sparklyr, dan dplyr disertakan dalam Databricks Runtime yang diinstal pada kluster Azure Databricks . Oleh karena itu, Anda tidak perlu memanggil install.package biasa sebelum Anda dapat mulai memanggil paket-paket ini. Namun, Anda masih harus memuat paket ini dengan library terlebih dahulu. Misalnya, dari dalam buku catatan R di ruang kerja Azure Databricks, jalankan kode berikut di sel buku catatan untuk memuat SparkR, sparklyr, dan dplyr:

library(SparkR)
library(sparklyr)
library(dplyr)

Menyambungkan sparklyr ke kluster

Setelah memuat sparklyr, Anda harus memanggil sparklyr::spark_connect untuk terhubung ke kluster, menentukan metode koneksi databricks. Misalnya, jalankan kode berikut dalam sel buku catatan untuk menyambungkan ke kluster yang menghosting buku catatan:

sc <- spark_connect(method = "databricks")

Sebaliknya, notebook Azure Databricks sudah membuat SparkSession pada kluster untuk digunakan dengan SparkR, sehingga Anda tidak perlu memanggil SparkR::sparkR.session sebelum Anda dapat mulai memanggil SparkR.

Mengunggah file data JSON ke ruang kerja Anda

Banyak contoh kode dalam artikel ini didasarkan pada data di lokasi tertentu di ruang kerja Azure Databricks Anda, dengan nama kolom dan jenis data tertentu. Data untuk contoh kode ini berasal dari file JSON bernama book.json dari dalam GitHub. Untuk mendapatkan file ini dan mengunggahnya ke ruang kerja Anda:

  1. Buka file books.json di GitHub dan gunakan editor teks untuk menyalin kontennya ke file bernama books.json di suatu tempat di komputer lokal Anda.
  2. Pada sidebar di ruang kerja Azure Databricks Anda, klik Catalog.
  3. Klik Buat Tabel.
  4. Pada tab Unggah File , letakkan file dari komputer lokal Anda ke kotak Letakkan file untuk diunggah. Atau pilih klik untuk menelusuri, kemudian menelusuri ke file books.json dari komputer lokal Anda.

Secara default, Azure Databricks mengunggah file lokal Anda ke lokasi DBFS di ruang kerja Anda dengan jalur .

Jangan klik Buat Tabel dengan UI atau Buat Tabel di Notebook. Contoh kode dalam artikel ini menggunakan data dalam file books.json yang diunggah di lokasi DBFS ini.

Membaca data JSON ke dalam DataFrame

Gunakan sparklyr::spark_read_json untuk membaca file JSON yang diunggah ke dalam DataFrame, menentukan koneksi, jalur ke file JSON, dan nama untuk representasi tabel internal data. Untuk contoh ini, Anda harus menentukan bahwa file book.json berisi beberapa baris. Menentukan skema kolom di sini bersifat opsional. Jika tidak, sparklyr menyimpulkan skema kolom secara default. Misalnya, jalankan kode berikut di sel buku catatan untuk membaca data file JSON yang diunggah ke dalam DataFrame bernama 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"
  )
)

Anda dapat menggunakan SparkR::head, SparkR::show, atau sparklyr::collect untuk mencetak baris pertama DataFrame. Secara default, head mencetak enam baris pertama secara default. show dan collect mencetak 10 baris pertama. Misalnya, jalankan kode berikut dalam sel buku catatan untuk mencetak baris pertama DataFrame bernama 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

Menjalankan kueri SQL, serta menulis pada dan membaca dari sebuah tabel

Anda dapat menggunakan fungsi dplyr untuk menjalankan kueri SQL pada DataFrame. Misalnya, jalankan kode berikut dalam sel buku catatan untuk menggunakan dplyr::group_by dan dployr::count guna mendapatkan jumlah berdasarkan penulis dari DataFrame bernama jsonDF. Gunakan dplyr::arrange dan dplyr::desc untuk mengurutkan hasil dalam urutan turun menurut hitungan. Kemudian cetak 10 baris pertama secara default.

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

Anda kemudian dapat menggunakan sparklyr::spark_write_table untuk menulis hasilnya ke tabel di Azure Databricks. Misalnya, jalankan kode berikut dalam sel buku catatan untuk menjalankan ulang kueri lalu tulis hasilnya ke tabel bernama json_books_agg:

group_by(jsonDF, author) %>%
  count() %>%
  arrange(desc(n)) %>%
  spark_write_table(
    name = "json_books_agg",
    mode = "overwrite"
  )

Untuk memverifikasi bahwa tabel telah dibuat, Anda kemudian dapat menggunakan sparklyr::sdf_sql bersama dengan SparkR::showDF untuk menampilkan data tabel. Misalnya, jalankan kode berikut dalam sel buku catatan untuk mengkueri tabel ke dalam DataFrame lalu gunakan sparklyr::collect untuk mencetak 10 baris pertama DataFrame secara default:

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

Anda juga dapat menggunakan sparklyr::spark_read_table untuk melakukan sesuatu yang serupa. Misalnya, jalankan kode berikut dalam sel buku catatan untuk mengkueri DataFrame sebelumnya bernama jsonDF ke dalam DataFrame lalu gunakan sparklyr::collect untuk mencetak 10 baris pertama DataFrame secara default:

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

Menambahkan kolom dan memperhitungkan nilai kolom dalam DataFrame

Anda dapat menggunakan fungsi dplyr untuk menambahkan kolom ke DataFrames dan untuk menghitung nilai kolom.

Misalnya, jalankan kode berikut dalam sel buku catatan untuk mendapatkan konten DataFrame bernama jsonDF. Gunakan dplyr::mutate untuk menambahkan kolom bernama today, dan isi kolom baru ini dengan tanda waktu saat ini. Kemudian tulis konten ini ke DataFrame baru bernama withDate dan gunakan dplyr::collect untuk mencetak 10 baris pertama DataFrame baru secara default.

Nota

dplyr::mutate hanya menerima argumen yang sesuai dengan fungsi bawaan Apache Hive (juga dikenal sebagai UDF) dan fungsi agregat bawaan (juga dikenal sebagai UDAF). Untuk informasi umum, lihat Hive Functions. Untuk informasi tentang fungsi terkait tanggal di bagian ini, lihat Fungsi Tanggal.

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

Sekarang gunakan dplyr::mutate untuk menambahkan dua kolom lagi ke konten withDate DataFrame. Kolom month dan year baru berisi bulan dan tahun numerik dari kolom today. Kemudian tulis konten ini ke DataFrame baru bernama withMMyyyy, dan gunakan dplyr::select bersama dengan dplyr::collect untuk mencetak kolom author, title, month dan year dari sepuluh baris pertama DataFrame baru secara default:

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

Sekarang gunakan dplyr::mutate untuk menambahkan dua kolom lagi ke konten withMMyyyy DataFrame. Kolom formatted_date baru berisi bagian yyyy-MM-dd dari kolom today, sementara kolom day baru berisi hari numerik dari kolom formatted_date baru. Kemudian tulis konten ini ke DataFrame baru bernama withUnixTimestamp, dan gunakan dplyr::select bersama dengan dplyr::collect untuk mencetak kolom title, formatted_date, dan day dari sepuluh baris pertama DataFrame baru secara default:

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

Membuat tampilan sementara

Anda dapat membuat tampilan sementara bernama dalam memori yang didasarkan pada DataFrames yang ada. Misalnya, jalankan kode berikut dalam sel buku catatan untuk menggunakan SparkR::createOrReplaceTempView untuk mendapatkan konten DataFrame sebelumnya bernama jsonTable dan buat tampilan sementara bernama timestampTable. Kemudian, gunakan sparklyr::spark_read_table untuk membaca konten tampilan sementara. Gunakan sparklyr::collect untuk mencetak 10 baris pertama tabel sementara secara default:

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

Melakukan analisis statistik pada DataFrame

Anda dapat menggunakan sparklyr bersama dengan dplyr untuk analisis statistik.

Misalnya, buat DataFrame untuk menjalankan statistik. Untuk melakukan ini, jalankan kode berikut dalam sel buku catatan untuk menggunakan sparklyr::sdf_copy_to untuk menulis konten himpunan data iris yang disertakan dalam R ke DataFrame bernama iris. Gunakan sparklyr::sdf_collect untuk mencetak 10 baris pertama tabel sementara secara default:

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

Sekarang gunakan dplyr::group_by untuk mengelompokkan baris menurut kolom Species. Gunakan dplyr::summarize bersama dengan dplyr::percentile_approx untuk menghitung statistik ringkasan berdasarkan kuantil ke-25, 50, 75, dan 100 dari kolom Sepal_Length menurut Species. Gunakan sparklyr::collect cetak hasilnya:

Nota

dplyr::summarize hanya menerima argumen yang sesuai dengan fungsi bawaan Apache Hive (juga dikenal sebagai UDF) dan fungsi agregat bawaan (juga dikenal sebagai UDAF). Untuk informasi umum, lihat Hive Functions. Untuk informasi tentang , lihatFungsi Agregat Bawaan (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

Hasil serupa dapat dihitung, misalnya, dengan menggunakan 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