Well Log Data Wrangling Menggunakan R

Aviandito
SedStrat
Published in
11 min readJan 27, 2020

Pesan sponsor: seluruh konten dan kode yang saya tulis akan selalu gratis dan dapat digunakan oleh siapa saja. Apabila Anda merasa terbantu, dukung saya melalui laman Saweria berikut. 10% dari dukungan Anda akan saya sumbangkan melalui Kitabisa. Terima kasih :)

Sebelumnya, saya ingin mengucapkan terima kasih atas sambutan yang (buat saya) lumayan hangat di LinkedIn atas tulisan pertama saya mengenai k-means clustering pada data log quad combo. Jadinya ketagihan nulis ’deh. Doakan semoga saya bisa nulis lebih banyak lagi tentang data science dan geoscience ya!

Kali ini saya akan membahas tentang the dirty work dalam alur kerja analisis data, yaitu data wrangling. Data wrangling adalah proses transformasi data ‘mentah’ menjadi format siap pakai dalam analisis. Banyak kesulitan yang umum ditemukan dalam tahapan ini, mulai dari jumlah file data mentah yang banyak, jenis file yang beragam, hingga perbedaan format penulisan data.

Umumnya proses ini menghabiskan waktu sekitar 70–80% dari keseluruhan jam kerja analisis data yang kita lakukan! Saya menghabiskan waktu beberapa hari untuk memuat dan merapikan data dari sumur South Barrow. Padahal, clustering untuk tulisan pertama saya cuma membutuhkan beberapa jam kerja saja.

Dari penjabaran singkat ini, saya langsung punya saran untuk pengambil keputusan di perusahaan migas yang ingin memanfaatkan big data (!): sebelum merekrut data scientist, rekrut dulu tim data engineer yang akan membuat pipeline ETL (Extract, Transform, Load) untuk semua data perusahaan, baik stream maupun batch data. Transformasi perusahaan Anda ke Era 4.0 (!) sulit terjadi sebelum perusahaan memiliki data warehouse yang rapi, siap pakai, dan mudah diakses. Karena tanpa data siap pakai, tidak akan ada analisis yang bisa dilakukan.

Tidak hanya untuk swasta, saya juga punya saran untuk Pemerintah ’nih. Menanggapi isu open data E&P Indonesia, semoga data yang diunggah sudah “dirapikan” dan bukan hanya asal unggah. Sepengalaman saya, banyak data (terutama data lama) berupa scan dan tidak bisa secara langsung dipakai dalam analisis. Inisiatif open data harus kita apresiasi, tapi semoga datanya banyak yang “ramah komputer” ya Pak/Bu! Supaya bisa cepat dianalisis dan memberikan dampak dalam penelitian serta pengembangan hulu migas Indonesia.

Cukup pengenalannya, let’s get da wranglin’ goin’. Berikut adalah package yang saya pakai dalam tulisan ini.

Memuat Data

Di tulisan ini, saya menggunakan dataset “Selected Data from Fourteen Wildcat Wells in the National Petroleum Reserve in Alaska” yang saya gunakan di tulisan pertama. Dataset ini terdiri dari 14 sumur yang dibor dan diselesaikan di tahun 1980-an, yang lokasinya ditunjukkan di gambar di bawah. Pada saat itu pemboran sumur-sumur wildcat ini sepertinya disponsori oleh Pemerintah Amerika Serikat melalui USGS, yang kemungkinan besar bertujuan untuk menarik investor swasta untuk mengeksplorasi daerah yang dianggap frontier di Amerika. Menarik, ya?

Dalam tulisan ini, saya akan berusaha memuat dan 3 jenis data dari seluruh sumur tersebut, yaitu:

  • Data log sumur;
  • Data top formasi; dan
  • Data porositas dan permeabilitas dari analisis core

Seorang bijak (kemungkinan besar Hadley Wickham dalam buku R for Data Science, tapi saya lupa) pernah berkata: “apabila kamu harus melakukan copy-paste sebanyak tiga kali atau lebih, maka tulislah fungsi dan/atau looping untuk itu”. Saya juga akan membuat fungsi dan looping untuk membaca data dari banyak sumur sekaligus, sehingga kita tidak perlu memuat tiap file satu per satu.

Menurut saya (selain kemampuan persuasi), fungsi dan/atau looping dalam kode adalah cara elegan dalam menyelesaikan permasalahan hidup, dan semoga Anda dapat merasakan hal yang sama!

Sebelum memulai, ada beberapa catatan mengenai dataset tersebut. Karena ketidaksempurnaan dalam digitalisasi, penyesuaian telah saya lakukan terhadap beberapa data asli supaya fungsi-fungsi dan looping yang saya buat dapat bekerja di seluruh data. Ada juga data yang belum ditabulasi tetapi saya temukan di scan laporan geologi, yang kemudian saya buatkan file .csv-nya. Jadi, disclaimer singkat: untuk mereplikasi secara sempurna, gunakan kode dan dataset yang saya unggah di tautan GitHub berikut, ya.

Data Log Sumur

Memuat data log sumur adalah pekerjaan termudah dalam tulisan ini, karena kita dapat menggunakan fungsi read_las() dari package petroreadr. Namun sebenarnya, faktor terpenting dalam kemudahan memuat seluruh data log sumur adalah karena format log sudah terstandar dalam format LAS. Sehingga, satu fungsi yang kita buat dapat membaca file .las dari sumber manapun. Hal ini perlu menjadi catatan dalam digitalisasi data: kalau bisa, gunakan format terstandar sehingga file menjadi “ramah komputer”.

Berikut adalah algoritma yang saya gunakan untuk membaca seluruh data log sumur:

  1. Temukan semua nama file berekstensi .las dengan fungsi list_file()
  2. Gunakan fungsi read_las() ke seluruh file tersebut (dalam tidyverse proses ini disebut “mapping”, yang saya implementasikan dengan fungsi map_df())

Sepertinya, saya berhasil memuat data seluruh sumur. Saya mengeceknya dengan menghitung jumlah sumur yang berhasil dimuat, dan mendapatkan 14 sumur sebagai hasil. Tugas pertama, selesai!

Data Top Formasi

Kita juga bisa menemukan data top formasi dalam dataset, namun sayangnya data tersebut berupa file teks (.txt) tidak terstruktur sehingga sulit untuk dibaca secara langsung oleh komputer. Di sini kreativitas kita diuji dalam melakukan pembacaan file tersebut.

Dosen saya Pak Chalid pernah berujar: “tidak ada yang tidak mungkin di dunia ini kecuali mencium sikut sendiri”. Menjadikan data teks menjadi dataframe terstruktur seharusnya bisa kita dilakukan…

Untuk melihat seperti apa bentuk dari file teks top formasi, saya menggunakan fungsi read_lines. Menariknya, ada pola-pola yang bisa kita gunakan untuk membaca file teks ini, misalnya tabel pencatatan dimulai dari baris WELL NAME. Selain itu, baris pencatatan berakhir sebelum kata-kata Data Source.

Dengan kebutuhan tersebut, saya menulis fungsi alaska_tops_reader(). Fungsi ini menerima nama file sebagai input, dan akan mengembalikan dataframe hasil pembacaan top formasi sebagai output. Berikut alur kerja fungsi tersebut:

  1. Gunakan read_table() untuk membaca file mulai dari baris sebelum WELL NAME, hingga baris sebelum Data Source. Fungsi grep()adalah fungsi yang sangat versatile dalam melakukan pencarian string dan tersedia di berbagai bahasa pemrograman. Dalam kasus seperti ini, grep() is your friend!
  2. Apabila pembacaan nama sumur terpisah, perbaiki. Serta buang kolom-kolom tidak penting
  3. Lakukan standardisasi nama kolom

Setelah itu, seperti halnya membaca data log, saya kembali menggunakan map_df() untuk menerapkan fungsi alaska_tops_reader()terhadap semua data top formasi. Di akhir proses, saya kembali melakukan penghitungan jumlah sumur dan rupanya saya berhasil memuat ke-14 sumur tersebut. Tugas kedua, selesai!

Data Porositas dan Permeabilitas dari Analisis Core

Dibanding data lainnya, data porositas dan permeabilitas core menjadi yang paling sulit dibaca dalam dataset ini. Ada beberapa hal yang menyulitkan pembacaan, misalnya perbedaan jumlah dan urutan kolom dalam file berformat .txt ini (contohnya ada sumur yang tidak memiliki pembacaan porositas core, ada yang menuliskan dengan urutan porositas dulu baru permeabilitas, dll.). Selain itu, membaca nama sumur untuk kemudian ikut dimuat juga menjadi tantangan tersendiri.

Kesulitan lainnya adalah terdapat perbedaan cara penulisan kolom dalam file-file tersebut. Kebanyakan file menggunakan spasi sebagai pemisah antar kolom, seperti pembacaan dari sumur AW1 di bawah ini. Namun…

… pada data sumur SB20 di bawah ini, pemisah antar kolom adalah tab (bukan spasi), yang direpresentasikan dengan \t. Apabila di fungsi-fungsi sebelumnya saya menggunakan read_table(), untuk membaca file SB20, saya perlu menggunakan varian lain yaitu read_table2()yang lebih ‘santai’ dalam aturan mengenai pemisahan antar kolom.

Penemuan ini menunjukkan bahwa konsistensi cara penulisan file sangatlah penting: perbedaan antara spasi atau tab saja bisa membuat calon pemakai data pusing! Untuk data tabular seperti contoh-contoh ini, menurut saya format .csv dapat meminimalisir inkonsistensi, serta lebih mudah dalam pembacaan di berbagai aplikasi.

Tantangan lainnya, nama sumur juga menjadi salah satu hal yang perlu kita baca, dan kemungkinan besar salah satu solusi terbaik adalah dengan menggunakan regular expression atau regex. Saya juga nggak ngerti-ngerti banget soal regex (Anda bisa menemukan banyak referensi untuk itu), dan disinilah Stack Overflow menjadi sahabat kita semua.

Dalam file-file ini, nama sumur selalu berada di antara string “Wildcat Well” dan “Permeability”. Untungnya, saya menemukan cara menggunakan regex untuk mengambil string di antara dua string di Stack Overflow, yang kemudian saya gunakan dalam fungsi str_extract() untuk mengambil nama sumur.

Berbekal semua hal tersebut, saya menulis fungsi alaska_pnp_reader(). Saya menjadikan fungsi baca yang dipakai menjadi argumen, sehingga pengguna bisa memilih mau menggunakan read_table2() untuk membaca data seperti contoh SB20 di atas, atau read_table()untuk membaca data lainnya. Fungsi ini juga secara otomatis membaca nama sumur, kemudian membuat kolom baru berupa nama sumur supaya sama dengan format pembacaan log sumur dan top formasi sebelumnya.

Untuk membaca, saya menggunakan pendekatan yang agak berbeda, untuk menunjukkan kepada Anda bahwa banyak jalan menuju ke Roma, apalagi dalam coding. Kalau sebelumnya saya menggunakan map_df() untuk melakukan mapping fungsi pembaca pada seluruh file, kali ini saya menggunakan the good ol’ looping untuk melakukan pembacaan. Berikut adalah tahapan looping yang saya lakukan:

  • Buat variabel kosong alaska_pnp untuk menyimpan data hasil pembacaan
  • Buat list nama file porositas dan permeabilitas, yang saya simpan sebagai pnp_list
  • Untuk semua elemen dalam pnp_list, masukkan nama file sebagai argumen fungsi alaska_pnp_reader(). Gunakan argumen read_function = 'read_table2' apabila nama file adalah SB20. Simpan hasil pembacaan dalam alaska_pnp
  • Berhenti apabila semua elemen pnp_list sudah dibaca

Pakai map_df() atau looping, pendekatan mana yang benar? Menurut saya sih hal tersebut bergantung pada kasus yang kita punya. Tetapi kalau kata rekan saya Muhammad Abduh, seorang computer scientist brilian dan berpengalaman, coding is an art form. Sehingga pada akhirnya semua adalah soal selera!

Setelah beberapa penyesuaian dan memuat data yang tidak ada file .txt nya, saya melakukan penghitungan jumlah sumur. Voila, terdapat 11 sumur yang berhasil terbaca, yang harusnya sesuai dengan ketersediaan data (CMIIW). Akhirnya semua tugas selesai!

Menggabungkan Data Well Log, Top Formasi, dan Porositas-Permeabilitas

Sekarang kita sudah memiliki semua dataframe berisi pembacaan data log sumur (alaska_well_log), pembacaan top formasi (alaska_top), dan pembacaan porositas serta permeabilitas core (alaska_pnp). Terkadang analisis yang Anda lakukan membutuhkan dataset yang memiliki semua data tersebut di atas. Lalu bagaimana cara untuk menyatukan ketiga dataframe tersebut menjadi satu?

Menggabungkan data dengan join

Apabila Anda memiliki keinginan untuk menjadi analis data, maka Anda wajib memahami join dalam relational database. Saya tidak akan membahas terlalu dalam soal join di sini, karena banyak artikel di internet yang membahas soal SQL Join. Intinya, join adalah cara “menggabungkan” beberapa tabel dalam sistem relational database. Gambar di bawah memberikan gambaran singkat mengenai apa itu join .

SQL Join (Sumber)

Tidyverse memiliki fungsi-fungsi join yang sangat mirip dengan SQL Join. Kalau sudah familiar dengan join di SQL, bagian ini akan sangat mudah dimengerti. Pada akhirnya saya menggunakan full_join() dan left_join() untuk menghasilkan integrasi data yang saya inginkan dari ketiga dataset tersebut.

Saya kemudian menuliskan dataset terintegrasi tersebut dalam format .csv. Apabila Anda tertarik untuk bermain-main dengan dataset yang saya muat, silakan diunduh dari repositori GitHub berikut ini!

Exploratory Data Analysis (EDA) Singkat, Kesimpulan, dan Saran

Sebetulnya masih banyak data yang belum saya muat namun penting dalam interpretasi geologi, seperti data latlong, saturasi air (Sw) core, dan lain-lain. Karena keterbatasan waktu, saya belum sempat mencoba memuat data-data tersebut. Apabila sempat, pasti akan saya muat dan perbaharui. Tetapi dengan data yang sudah saya muat, saya akan berusaha menunjukkan kesempatan-kesempatan analisis yang bisa dilakukan apabila kita memiliki data lengkap dan terintegrasi.

Kalau Anda memperhatikan budaya populer, Anda pasti tidak asing dengan album Unknown Pleasure rilisan unit post-punk legendaris Joy Division. Nah, cover album tersebut terlihat seperti gelombang-gelombang seismik, dan R punya package ggridges untuk memvisualisasikan data dengan gaya tersebut.

Plot di bawah ini menunjukkan visualisasi distribusi data log quad combo serta porositas dan permeabilitas core, berdasarkan formasi. Perhatikan bahwa saya menggunakan semua data yang saya muat dalam plot tersebut. Untuk kerapian plot, saya membatasi tiga formasi target utama di wilayah eksplorasi, yaitu Sag River Sandstone, Pebble Shale Unit, dan Kingak Shale.

Ada saja ide analisis lanjutan yang bisa kita tarik dari plot ini. Sekilas dapat dilihat bahwa hampir semua log di semua formasi memiliki distribusi dengan beberapa puncak. Kemungkinan besar hal tersebut terjadi karena formasi-formasi tersebut terdiri dari beberapa fasies. Dari sini, kita bisa menyarankan analisis lanjutan berupa rock typing untuk karakterisasi reservoir yang lebih baik. Selain itu, dapat dilihat bahwa median porositas dan permeabilitas core di Pebble Shale Unit relatif lebih tinggi dibanding formasi lainnya. Apakah ini berarti kualitas reservoir di formasi tersebut lebih baik? Hal ini tentunya harus dijawab dengan analisis lanjutan.

Sekarang lupakan Joy Division dan mari kembali ke sahabat setia semua log analyst: cross plot. Di bawah ini, saya membuat cross plot porositas dan permeabilitas core berdasarkan formasi. Permeabilitas diplot dengan menggunakan skala logaritmik. Kemudian saya menambahkan garis regresi linear porositas terhadap permeabilitas. Terakhir, saya menggunakan warna untuk mengidentifikasi sumur asal data core tersebut.

Cross plot di bawah menunjukkan bahwa porositas dan permeabilitas berkorelasi positif, dan punya korelasi yang cukup kuat. Sepertinya, kita bisa membuat model prediksi permeabilitas yang cukup baik dari data yang kita punya.

Menariknya, hubungan antara porositas dan permeabilitas di Sag River Sandstone agak berbeda dibanding formasi lainnya. Apabila kita memperhatikan data Sag River Sandstone, dapat dilihat bahwa perbedaan gradien garis regresi tersebut kemungkinan disebabkan karena sekumpulan data dengan porositas relatif tinggi, namun permeabilitas relatif rendah (di kanan bawah garis regresi).

Kita dapat mengidentifikasi bahwa data tersebut berasal dari suatu sumur, yaitu East Simpson 2 (ES-2), yang sepertinya harus kita pisahkan apabila kita menyiapkan dataset training untuk model permeabilitas. Kalau melihat posisi ES-2 di peta persebaran sumur, memang agak terpisah di bagian paling timur dari sumur lainnya yang memiliki data core Sag River Sandstone. Apakah fasies Sag River Sandstone di ES-2 berbeda dengan sumur lainnya? Mungkinkah perbedaan ini dipengaruhi oleh struktur? Yang jelas hal tersebut membutuhkan penelitian lebih lanjut.

Update: Membuat model porositas-permeabilitas memang menarik, tetapi berdasarkan diskusi dengan Pak Yulianto Jong di kolom komentar LinkedIn, jangan lupa prinsip “garbage in, garbage out”. Diperlukan kontrol kualitas data core, serta keterangan mengenai kandungan mineral lempung, XRD-SEM, dan lain sebagainya sebelum kita bisa mendapatkan model permeabilitas yang dapat dipercaya! Jangan lupa dicatat ya kawan-kawan.

Sejujurnya post kali ini cukup memakan waktu karena tantangan yang ada. Tetapi saya cukup menikmati proses penulisan fungsi yang bisa membaca banyak data migas sekaligus. Bagi saya hal tersebut cukup memuaskan! Dari pengalaman ini, saya memiliki beberapa saran, yaitu:

  • Dalam digitasi data eksplorasi dan produksi, dibutuhkan domain knowledge agar data terstruktur dengan baik
  • Diperlukan standardisasi format penulisan data supaya data menjadi terstruktur dan lebih cepat diproses
  • Gunakan format ramah komputer dalam mengunggah. Format .las untuk data well log serta .csv untuk tabulasi mudah dibaca
  • Pembacaan open data dari alamat web seperti contoh akan lebih efektif apabila menggunakan teknik web scraping, dibanding mengunduh file satu per satu seperti yang saya lakukan. Beautiful Soup yang ditulis dalam Python adalah tool yang baik untuk melakukan hal tersebut
  • Untuk perusahaan migas: persingkat waktu dari pencarian data hingga analisis dengan memanfaatkan cloud storage dan sistem database(mungkin berbasis SQL?) yang mudah diakses siapapun dalam perusahaan melalui software apapun
  • Untuk Pemerintah: bayangkan kemungkinan yang bisa terjadi kalau data migas terbuka dan siap dianalisis. Penelitian hulu migas akan lebih banyak: model permeabilitas yang lebih akurat bisa ditemukan, identifikasi fluida lebih baik, dan lain-lain. Bahkan dampaknya bisa lebih luas daripada keilmuan geosains: pasar finansial bisa menjadi lebih efisien karena data migas yang terbuka, dan seterusnya!

Demikian tulisan saya kali ini. Seperti biasa, semua kode dan dataset yang saya gunakan telah saya unggah di repo GitHub berikut. Menemukan kesalahan dalam proses pemuatan data yang saya lakukan? Ada kritik mengenai fungsi yang saya tulis? Apakah saran yang saya sampaikan tidak mungkin dilakukan? Seperti biasa, komentar Anda sangat saya tunggu-tunggu, dan mari berdiskusi!

--

--

Aviandito
SedStrat

Interested in cool stuff ranging from Formula One to Geoscience. All views are personal.