Saya memiliki kumpulan data yang memiliki lebih dari 500 juta catatan. Saya ingin menerapkan klausa group by pada beberapa kolom untuk mendapatkan hitungan. Saat mengelompokkan, saya juga perlu memastikan bahwa jumlah hasil hanya untuk nilai tertentu di kolom.

Saya memiliki Tabel Pinjaman yang memiliki customer_id,loan_id, angsuran_amt, angsuran_status Installment_status berisi beberapa nilai 'B', 'N', 'C'

Dalam satu pertanyaan, saya ingin tahu untuk setiap customer_id, loan_id, berapa jumlah total angsuran, Jumlah angsuran yang hanya memiliki 'B' dan Jumlah angsuran yang memiliki 'C'.

Saya baru mengenal SparkR mencoba melakukan sesuatu seperti di bawah ini-

RESULT <- summarize(
  groupBy(LOAN, "customer_id", "loan_id"),
  NO_OF_Installment=count(LOAN$installment_amt),
  BILLED_INSTALLMENTS=count(LOAN$$installment_status=='B'),
  CCANCELLED_INSTALLMENT=count(LOAN$$installment_status=='C')
)

Itu memberi saya jumlah yang sama untuk billed_installment serta cancelled_installment.

Saya tidak yakin bahwa memfilter sambil menghitung akan berfungsi. Saya tidak melihat apa pun di dokumentasi. Tetapi saya telah melihat kode ini berfungsi di R.

0
Rajeev 9 Agustus 2019, 07:55

1 menjawab

Jawaban Terbaik

Saya menemukan kode SparkR sedikit lebih mudah dibaca dengan pipa karena terlihat lebih mirip dengan versi Python atau Scala yang sama, jadi saya akan menggunakan magrittr.

library(magrittr)

Ide dasarnya adalah menggunakan metode ifelse.

Di SparkQL:

LOAN %>% createOrReplaceTempView('LOAN')
sql("
select customer_id, loan_id, count(installment_amt) as no_of_installment,
       count(if(installment_status = 'B', 1, NULL)) as billed_installments,
       count(if(installment_status = 'C', 1, NULL)) as cancelled_installments
from loan
group by customer_id, loan_id
") %>% summarize

Dalam "asli" SparkR seharusnya:

LOAN %>% groupBy('customer_id', 'loan_id') %>%
  summarize(
    NO_OF_Installment = count(.$installment_amt),
    BILLED_INSTALLMENTS = count(ifelse(.$installment_status == 'B', 1, NA)),
    CANCELLED_INSTALLMENTS = count(ifelse(.$installment_status == 'C', 1, NA))
  )

Saya tidak 100% yakin apakah Anda memerlukan NA atau NULL sebagai nilai no di ifelse, tetapi saya menemukan jawaban ini menggunakan NA.


Mengenai mengapa pendekatan Anda sendiri tidak berhasil, menurut saya pendekatan Anda akan berhasil untuk sum alih-alih count.

count menghitung jumlah baris non-NULL dalam sebuah kolom. LOAN$installment_status=='C' adalah kolom boolean, jadi hanya akan menjadi NULL jika LOAN$installment_status adalah NULL. count tidak peduli dengan nilai sebenarnya kolom -- bahkan tidak peduli dengan tipe data.

base R terdekat dengan count adalah length. length(numeric(100)) sama dengan length(logical(100)).

Sebaliknya, Anda mungkin lebih nyaman memikirkan ini sebagai sum -- setara dengan base R seperti sum(installment_status == 'B'). Dalam SparkR, ini akan terlihat seperti

sum(as.integer(.$installment_status == 'B'))
# or
sum(ifelse(.$installment_status == 'B', 1, 0))

Sayangnya sementara base R secara implisit mengubah tipe logical menjadi integer ketika kita sum, SparkR memerlukan konversi eksplisit, oleh karena itu dua alternatif ini yang membuat konversi dari boolean hingga integer eksplisit.

1
MichaelChirico 9 Agustus 2019, 05:53