Aracılığıyla paylaş


R'de DataFrame'ler ve tablolarla çalışma

Önemli

Databricks'teki SparkR, Databricks Runtime 16.0 ve üzeri sürümlerinde kullanım dışı bırakılmıştır. Databricks bunun yerine sparklyr kullanılmasını önerir.

Bu makalede R , Spark DataFramesve bellek içi tablolarla çalışmak için sparklyrve dplyr SparkRgibi R paketlerinin nasıl kullanılacağı açıklanmaktadır.

SparkR, sparklyr ve dplyr ile çalışırken, bu paketlerin tümüyle belirli bir işlemi tamamlayabileceğinizi ve en rahat olduğunuz paketi kullanabileceğinizi görebilirsiniz. Örneğin, sorgu çalıştırmak için SparkR::sql, sparklyr::sdf_sqlve dplyr::selectgibi işlevleri çağırabilirsiniz. Diğer durumlarda, bu paketlerden yalnızca bir veya iki tanesiyle bir işlemi tamamlayabilirsiniz ve seçtiğiniz işlem kullanım senaryonuza bağlıdır. Örneğin, sparklyr::sdf_quantile çağırma şekliniz, her iki işlev de nicelleri hesaplasa da dplyr::percentile_approxçağırma yönteminizden biraz farklıdır.

SQL'i SparkR ile sparklyr arasında köprü olarak kullanabilirsiniz. Örneğin, sparklyr ile oluşturduğunuz tabloları sorgulamak için SparkR::sql kullanabilirsiniz. SparkR ile oluşturduğunuz tabloları sorgulamak için sparklyr::sdf_sql kullanabilirsiniz. dplyr kodu her zaman çalıştırılmadan önce bellekte SQL'e çevrilir. Ayrıca bkz. API birlikte çalışabilirlik ve SQL Çevirisi.

SparkR, sparklyr ve dplyr yükleyin

SparkR, sparklyr ve dplyr paketleri,Azure Databricks kümelerine yüklenen Databricks Runtime'a eklenir. Bu nedenle, bu paketleri çağırmaya başlamadan önce her zamanki install.package çağırmanız gerekmez. Ancak, bu paketleri önce library ile yüklemeniz gerekir. Örneğin, Azure Databricks çalışma alanında R not defterinin içinden aşağıdaki kodu bir not defteri hücresinde çalıştırarak SparkR, sparklyr ve dplyr'yi yükleyin:

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

Sparklyr'ı kümeye bağlama

Sparklyr'ı yükledikten sonra, sparklyr::spark_connect bağlantı yöntemini belirterek kümeye bağlanmak için databricks çağırmanız gerekir. Örneğin, not defterini barındıran kümeye bağlanmak için not defteri hücresinde aşağıdaki kodu çalıştırın:

sc <- spark_connect(method = "databricks")

Buna karşılık, Azure Databricks not defteri SparkR ile kullanılmak üzere kümede zaten bir SparkSession oluşturur, bu nedenle SparkR'yi çağırmaya başlamadan önce SparkR::sparkR.session çağırmanız gerekmez.

Çalışma alanınıza JSON veri dosyası yükleme

Bu makaledeki kod örneklerinin çoğu, Azure Databricks çalışma alanınızdaki belirli bir konumdaki belirli sütun adları ve veri türleri içeren verileri temel alır. Bu kod örneğinin verileri GitHub'ın içinden book.json adlı bir JSON dosyasından kaynaklanır. Bu dosyayı almak ve çalışma alanınıza yüklemek için:

  1. GitHub'da books.json dosyasına gidin ve içeriğini yerel makinenizde bir yere books.json adlı bir dosyaya kopyalamak için bir metin düzenleyicisi kullanın.
  2. Azure Databricks çalışma alanınızın kenar çubuğunda Katalogöğesine tıklayın.
  3. tablo oluşturtıklayın.
  4. Dosya Yükle sekmesinde, yerel makinenizden books.json dosyasını Dosya yükleme kutusuna bırakın. İsterseniz tıklayarakgöz atabilir ve yerel makinenizden books.json dosyasına göz atabilirsiniz.

Varsayılan olarak, Azure Databricks yerel books.json dosyanızı yolu ile çalışma alanınızdaki /FileStore/tables/books.json konumuna yükler.

kullanıcı arabirimi Tablo Oluştur'a veya Not DefteriTablo Oluştur'a tıklamayın. Bu makaledeki kod örnekleri, DBFS konumunda karşıya yüklenen books.json dosyasındaki verileri kullanmaktadır.

JSON verilerini DataFrame'de okuma

DataFrame'e yüklenen JSON dosyasını okumak için sparklyr::spark_read_json kullanın; bağlantı, JSON dosyasının yolu ve verilerin iç tablo gösterimi için bir ad belirtin. Bu örnekte, book.json dosyasının birden çok satır içerdiğini belirtmeniz gerekir. Sütunların şemasının burada belirtilmesi isteğe bağlıdır. Aksi takdirde sparklyr varsayılan olarak sütunların şemasını çıkartır. Örneğin, karşıya yüklenen JSON dosyasının verilerini jsonDFadlı bir DataFrame'e okumak için bir not defteri hücresinde aşağıdaki kodu çalıştırın:

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"
  )
)

DataFrame'in ilk satırlarını yazdırmak için SparkR::head, SparkR::showveya sparklyr::collect kullanabilirsiniz. Varsayılan olarak, head ilk altı satırı yazdırır. show ve collect, ilk 10 satırı yazdırır. Örneğin, jsonDFadlı DataFrame'in ilk satırlarını yazdırmak için bir not defteri hücresinde aşağıdaki kodu çalıştırın:

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 sorguları çalıştırma ve tabloya yazma ve tablodan okuma

Bir DataFrame üzerinde SQL sorguları çalıştırmak için dplyr işlevlerini kullanabilirsiniz. Örneğin, yazara göre sayıları almak için dplyr::group_by ve dployr::count'i kullanarak aşağıdaki kodu not defteri hücresinde çalıştırın ve bu sayıları jsonDFadlı DataFrame'den alın. Sonucu sayılara göre azalan düzende sıralamak için dplyr::arrange ve dplyr::desc kullanın. Ardından varsayılan olarak ilk 10 satırı yazdırın.

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

Daha sonra sonucu Azure Databricks'teki bir tabloya yazmak için sparklyr::spark_write_table kullanabilirsiniz. Örneğin, aşağıdaki kodu bir not defteri hücresinde çalıştırarak sorguyu yeniden çalıştırın ve ardından sonucu json_books_aggadlı bir tabloya yazın:

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

Tablonun oluşturulduğunu doğrulamak için sparklyr::sdf_sql ve SparkR::showDF kullanarak tablonun verilerini görüntüleyebilirsiniz. Örneğin, aşağıdaki kodu bir not defteri hücresinde çalıştırarak tabloyu DataFrame'e sorgulayın ve varsayılan olarak DataFrame'in ilk 10 satırını yazdırmak için sparklyr::collect kullanın:

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

Benzer bir şey yapmak için sparklyr::spark_read_table de kullanabilirsiniz. Örneğin, bir not defteri hücresinde aşağıdaki kodu çalıştırarak jsonDF adlı önceki DataFrame'i bir DataFrame'e sorgulayın ve varsayılan olarak DataFrame'in ilk 10 satırını yazdırmak için sparklyr::collect kullanın:

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

DataFrame'de sütun ekleyin ve sütun değerlerini hesaplayın.

DataFrame'lere sütun eklemek ve sütunların değerlerini hesaplamak için dplyr işlevlerini kullanabilirsiniz.

Örneğin, jsonDFadlı DataFrame'in içeriğini almak için aşağıdaki kodu bir not defteri hücresinde çalıştırın. todayadlı bir sütun eklemek ve bu yeni sütunu geçerli zaman damgasıyla doldurmak için dplyr::mutate kullanın. Ardından bu içerikleri withDate adlı yeni bir DataFrame'e yazın ve yeni DataFrame'in ilk 10 satırını varsayılan olarak yazdırmak için dplyr::collect kullanın.

Not

dplyr::mutate yalnızca Hive'ın yerleşik fonksiyonlarına (UDF olarak da bilinir) ve yerleşik toplama fonksiyonlarına (UDAF olarak da bilinir) uyan bağımsız değişkenleri kabul eder. Genel bilgi için bkz. Hive İşlevleri. Bu bölümdeki tarihle ilgili işlevler hakkında bilgi için bkz. tarih İşlevleri.

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

Şimdi withDate DataFrame'in içeriğine iki sütun daha eklemek için dplyr::mutate kullanın. Yeni month ve year sütunları, today sütunundaki sayısal ayı ve yılı içerir. Ardından bu içerikleri withMMyyyyadlı yeni bir DataFrame'e yazın ve varsayılan olarak yeni DataFrame'in ilk on satırının author, title, month ve year sütunlarını yazdırmak için dplyr::collect ile birlikte dplyr::select kullanın:

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

Şimdi withMMyyyy DataFrame'in içeriğine iki sütun daha eklemek için dplyr::mutate kullanın. Yeni formatted_date sütunları today sütunundan yyyy-MM-dd bölümünü içerirken, yeni day sütunu yeni formatted_date sütununun sayısal gününü içerir. Ardından bu içerikleri withUnixTimestampadlı yeni bir DataFrame'e yazın ve varsayılan olarak yeni DataFrame'in ilk on satırının title, formatted_dateve day sütunlarını yazdırmak için dplyr::collect ile birlikte dplyr::select kullanın:

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

Geçici görünüm oluşturma

Bellekte mevcut DataFrame'leri temel alan adlandırılmış geçici görünümler oluşturabilirsiniz. Örneğin, bir not defteri hücresinde aşağıdaki kodu çalıştırarak SparkR::createOrReplaceTempView kullanarak jsonTable adlı önceki DataFrame'in içeriğini alın ve timestampTableadlı geçici bir görünüm oluşturun. Ardından geçici görünümün içeriğini okumak için sparklyr::spark_read_table kullanın. Geçici tablonun ilk 10 satırını varsayılan olarak yazdırmak için sparklyr::collect kullanın:

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

DataFrame üzerinde istatistiksel analiz gerçekleştirme

İstatistiksel analizler için sparklyr ve dplyr kullanabilirsiniz.

Örneğin, istatistikleri çalıştırmak için bir DataFrame oluşturun. Bunu yapmak için, aşağıdaki kodu bir not defteri hücresinde çalıştırarak R'de yerleşik sparklyr::sdf_copy_to veri kümesinin içeriğini irisadlı bir DataFrame'e yazmak için iris kullanın. Geçici tablonun ilk 10 satırını varsayılan olarak yazdırmak için sparklyr::sdf_collect kullanın:

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

Şimdi satırları Species sütununa göre gruplandırmak için dplyr::group_by kullanın. özet istatistiklerini Speciesgöre Sepal_Length sütununun 25., 50., 75. ve 100. nicellerine göre hesaplamak için dplyr::percentile_approx ile birlikte dplyr::summarize kullanın. Sonuçları yazdırmak için sparklyr::collect kullanın.

Not

dplyr::summarize yalnızca Hive'ın yerleşik fonksiyonlarına (UDF olarak da bilinir) ve yerleşik toplama fonksiyonlarına (UDAF olarak da bilinir) uyan bağımsız değişkenleri kabul eder. Genel bilgi için bkz. Hive İşlevleri. percentile_approxhakkında bilgi için bkz. Yerleşik Toplama İşlevleri (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

Benzer sonuçlar, örneğin sparklyr::sdf_quantilekullanılarak hesaplanabilir:

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