Ketika saya melakukan proyek R dengan kompleksitas apa pun, skrip saya dengan cepat menjadi panjang dan membingungkan.
Apa saja praktik yang bisa saya adopsi sehingga kode saya akan selalu menyenangkan untuk bekerja dengannya? Saya sedang memikirkan hal-hal seperti
- Penempatan fungsi dalam file sumber
- Kapan memecahkan sesuatu ke file sumber lain
- Apa yang seharusnya ada di file master
- Menggunakan fungsi sebagai unit organisasi (apakah ini bermanfaat mengingat R membuatnya sulit untuk mengakses keadaan global)
- Indentasi / praktik pemutusan jalur.
- Perlakukan (seperti {?
- Letakkan hal-hal seperti)} pada 1 atau 2 baris?
Pada dasarnya, apa aturan praktis Anda untuk mengatur skrip R besar?
r
package
conventions
code-organization
project-organization
Dan Goldstein
sumber
sumber
ProjectTemplate
paketnya.Jawaban:
Jawaban standar adalah dengan menggunakan paket - lihat manual Penulisan R Extensions serta berbagai tutorial di web.
Ini memberi Anda
R CMD check
Hanya menjalankan
source()
kode berfungsi untuk cuplikan yang sangat singkat. Segala sesuatu yang lain harus dalam sebuah paket - bahkan jika Anda tidak berencana untuk menerbitkannya karena Anda dapat menulis paket internal untuk repositori internal.Adapun bagian 'cara mengedit', manual R Internals memiliki standar pengkodean R yang sangat baik di Bagian 6. Jika tidak, saya cenderung menggunakan default dalam mode ESS Emacs .
Pembaruan 2008-Agustus-13: David Smith baru saja membuat blog tentang Panduan Gaya R Google .
sumber
Saya suka menempatkan fungsi yang berbeda di file mereka sendiri.
Tapi saya tidak suka sistem paket R. Agak sulit digunakan.
Saya lebih suka alternatif yang ringan, untuk menempatkan fungsi file di dalam lingkungan (apa yang setiap bahasa lain sebut "namespace") dan melampirkannya. Sebagai contoh, saya membuat grup fungsi 'util' seperti:
Ini semua dalam file util.R . Ketika Anda sumber itu, Anda mendapatkan lingkungan 'util' sehingga Anda dapat menelepon
util$bgrep()
dan semacamnya; tetapi lebih jauh lagi,attach()
panggilan itu membuatnya begitu adilbgrep()
dan langsung berfungsi. Jika Anda tidak meletakkan semua fungsi itu di lingkungan mereka sendiri, mereka akan mencemari namespace tingkat atas penerjemah (yangls()
menunjukkan).Saya mencoba mensimulasikan sistem Python, di mana setiap file adalah modul. Itu akan lebih baik untuk dimiliki, tetapi ini tampaknya OK.
sumber
sys.source
:MyEnv <- attach(NULL, name=s_env); sys.source(file, MyEnv)
. Saya bahkan mendeklarasikan (di lingkungannya sendiri!) Saat memulai fungsisys.source2
yang akan mencari jika lingkungan dengan nama yang sama sudah ada di sini dan mengumpankan yang ini alih-alih membuat yang baru. Itu membuat menambahkan fungsi pribadi cepat, mudah dan agak terorganisir :-)Ini mungkin terdengar agak jelas terutama jika Anda seorang programmer, tetapi inilah cara saya berpikir tentang unit kode logis dan fisik.
Saya tidak tahu apakah ini kasus Anda, tetapi ketika saya bekerja di R, saya jarang memulai dengan program rumit yang besar dalam pikiran. Saya biasanya mulai dalam satu skrip dan memisahkan kode menjadi unit yang dapat dipisahkan secara logis, sering menggunakan fungsi. Manipulasi data dan kode visualisasi ditempatkan dalam fungsinya sendiri, dll. Dan fungsi tersebut dikelompokkan bersama dalam satu bagian file (manipulasi data di bagian atas, kemudian visualisasi, dll). Pada akhirnya Anda ingin berpikir tentang cara membuatnya lebih mudah bagi Anda untuk mempertahankan skrip Anda dan menurunkan tingkat cacat.
Seberapa halus / kasarnya Anda membuat fungsi Anda akan bervariasi dan ada berbagai aturan praktis: misalnya 15 baris kode, atau "suatu fungsi harus bertanggung jawab untuk melakukan satu tugas yang diidentifikasi dengan namanya", dll. Jarak tempuh Anda akan bervariasi . Karena R tidak mendukung referensi panggilan-oleh, saya biasanya berbeda-beda membuat fungsi saya terlalu halus ketika melibatkan melewati frame data atau struktur serupa di sekitar. Tapi ini mungkin kelebihan kompensasi untuk beberapa kesalahan kinerja konyol ketika saya pertama kali mulai dengan R.
Kapan mengekstraksi unit logis ke unit fisik mereka sendiri (seperti file sumber dan pengelompokan yang lebih besar seperti paket)? Saya punya dua kasus. Pertama, jika file menjadi terlalu besar dan bergulir di antara unit yang tidak berhubungan secara logis adalah gangguan. Kedua, jika saya memiliki fungsi yang dapat digunakan kembali oleh program lain. Saya biasanya memulai dengan menempatkan beberapa unit yang dikelompokkan, misalnya fungsi manipulasi data, ke dalam file terpisah. Saya kemudian dapat sumber file ini dari skrip lain.
Jika Anda akan menggunakan fungsi Anda, maka Anda harus mulai berpikir tentang paket. Saya tidak menggunakan kode R dalam produksi atau untuk digunakan kembali oleh orang lain karena berbagai alasan (secara singkat: budaya org lebih suka bahasa lain, masalah tentang kinerja, GPL, dll). Juga, saya cenderung untuk terus memperbaiki dan menambah koleksi file saya yang bersumber, dan saya lebih suka tidak berurusan dengan paket ketika saya melakukan perubahan. Jadi, Anda harus memeriksa jawaban terkait paket lainnya, seperti Dirk, untuk detail lebih lanjut di bagian depan ini.
Akhirnya, saya pikir pertanyaan Anda belum tentu khusus untuk R. Saya akan sangat merekomendasikan membaca Kode Lengkap oleh Steve McConnell yang berisi banyak kebijaksanaan tentang masalah-masalah seperti itu dan praktik pengkodean pada umumnya.
sumber
Saya setuju dengan saran Dirk! IMHO, mengatur program Anda dari skrip sederhana ke paket yang terdokumentasi adalah, untuk Pemrograman dalam R, seperti beralih dari Word ke TeX / LaTeX untuk menulis. Saya sarankan untuk melihat Paket R Membuat yang sangat berguna : Tutorial oleh Friedrich Leisch.
sumber
Jawaban singkat saya:
Saya percaya R semakin banyak digunakan dalam produksi, sehingga kebutuhan untuk kode yang dapat digunakan kembali lebih besar dari sebelumnya. Saya menemukan penerjemah jauh lebih kuat dari sebelumnya. Tidak ada keraguan bahwa R adalah 100-300x lebih lambat dari C, tetapi biasanya bottleneck terkonsentrasi di sekitar beberapa baris kode, yang dapat didelegasikan ke C / C ++. Saya pikir itu akan menjadi kesalahan untuk mendelegasikan kekuatan R dalam manipulasi data dan analisis statistik ke bahasa lain. Dalam hal ini, penalti kinerja rendah, dan dalam hal apa pun sepadan dengan penghematan dalam upaya pembangunan. Jika waktu eksekusi adalah masalahnya, kita semua akan menjadi assembler menulis.
sumber
Saya bermaksud mencari tahu cara menulis paket tetapi belum menginvestasikan waktu. Untuk setiap proyek mini saya, saya menyimpan semua fungsi tingkat rendah saya di folder yang disebut 'fungsi /', dan sumber mereka ke ruang nama terpisah yang saya buat secara eksplisit.
Baris kode berikut akan membuat lingkungan bernama "fungsi saya" di jalur pencarian jika belum ada (menggunakan lampiran), dan mengisinya dengan fungsi-fungsi yang terdapat dalam file .r di direktori 'functions /' saya (menggunakan sys.source). Saya biasanya meletakkan baris-baris ini di bagian atas skrip utama saya dimaksudkan untuk "antarmuka pengguna" dari mana fungsi tingkat tinggi (memanggil fungsi tingkat rendah) disebut.
Saat Anda melakukan perubahan, Anda selalu dapat mengisinya kembali dengan baris yang sama, atau menggunakan sesuatu seperti
untuk mengevaluasi penambahan / modifikasi di lingkungan yang Anda buat.
Itu kludgey, saya tahu, tetapi menghindari harus terlalu formal tentang hal itu (tetapi jika Anda mendapatkan kesempatan saya mendorong sistem paket - mudah-mudahan saya akan bermigrasi seperti itu di masa depan).
Adapun konvensi pengkodean, ini adalah satu-satunya hal yang saya lihat mengenai estetika (saya suka mereka dan secara longgar mengikuti tapi saya tidak menggunakan terlalu banyak kurung kurawal di R):
http://www1.maths.lth.se/help/R/RCC/
Ada "konvensi" lain tentang penggunaan [, drop = FALSE] dan <- seperti yang disarankan operator penugasan dalam berbagai presentasi (biasanya keynote) di useR! konferensi, tapi saya rasa tidak ada yang ketat (meskipun [, drop = FALSE] berguna untuk program di mana Anda tidak yakin dengan input yang Anda harapkan).
sumber
Hitung saya sebagai orang lain yang mendukung paket. Saya akan mengakui bahwa saya sangat miskin dalam menulis halaman manual dan sketsa sampai jika / ketika saya harus (yaitu dibebaskan), tetapi itu membuat cara yang sangat praktis untuk meng-bundel sumber doe. Plus, jika Anda serius menjaga kode Anda, poin-poin yang diangkat oleh Dirk masuk ke dalam plya.
sumber
Saya juga setuju. Gunakan fungsi package.skeleton () untuk memulai. Bahkan jika Anda berpikir kode Anda tidak akan pernah berjalan lagi, ini dapat membantu memotivasi Anda untuk membuat kode yang lebih umum yang dapat menghemat waktu Anda nanti.
Sedangkan untuk mengakses lingkungan global, itu mudah dengan << - operator, meskipun tidak disarankan.
sumber
Karena belum belajar bagaimana menulis paket, saya selalu mengorganisasikannya dengan sumber sub skrip. Mirip dengan kelas menulis tetapi tidak terlibat. Secara pemrograman tidak elegan, tetapi saya menemukan saya membangun analisis dari waktu ke waktu. Setelah saya memiliki bagian besar yang berfungsi, saya sering memindahkannya ke skrip yang berbeda dan hanya sumber karena akan menggunakan objek ruang kerja. Mungkin saya perlu mengimpor data dari beberapa sumber, mengurutkan semuanya dan menemukan persimpangan. Saya mungkin memasukkan bagian itu ke dalam skrip tambahan. Namun, jika Anda ingin mendistribusikan "aplikasi" Anda untuk orang lain, atau menggunakan beberapa input interaktif, sebuah paket mungkin merupakan rute yang baik. Sebagai seorang peneliti, saya jarang perlu mendistribusikan kode analisis saya tetapi saya SERING perlu menambah atau menyesuaikannya.
sumber
Saya juga mencari cawan suci dari alur kerja yang tepat untuk menyusun proyek R besar. Saya menemukan tahun lalu paket ini disebut rsuite , dan, tentu saja, itu yang saya cari. Paket R ini secara eksplisit dikembangkan untuk penyebaran proyek R besar tetapi saya menemukan bahwa itu dapat digunakan untuk proyek R yang lebih kecil, ukuran sedang, dan ukuran besar. Saya akan memberikan tautan ke contoh dunia nyata dalam satu menit (di bawah), tetapi pertama-tama saya ingin menjelaskan paradigma baru dalam membangun proyek R dengan
rsuite
.Catatan. Saya bukan pencipta atau pengembang
rsuite
.Kami telah melakukan semua kesalahan proyek dengan RStudio; tujuannya tidak boleh menjadi penciptaan proyek atau paket tetapi dari ruang lingkup yang lebih besar. Di rsuite, Anda membuat proyek super atau proyek master, yang menampung proyek R standar dan paket R, dalam semua kombinasi yang memungkinkan.
Dengan memiliki proyek super R Anda tidak perlu lagi Unix
make
untuk mengelola tingkat proyek R yang lebih rendah di bawahnya; Anda menggunakan skrip R di bagian atas. Mari ku tunjukkan. Saat Anda membuat proyek master rsuite, Anda mendapatkan struktur folder ini:Folder
R
adalah tempat Anda meletakkan skrip manajemen proyek Anda, yang akan digantimake
.Folder
packages
adalah folder tempatrsuite
menyimpan semua paket yang menyusun proyek-super. Anda juga dapat menyalin rekatkan paket yang tidak dapat diakses dari internet, dan rsuite juga akan membuatnya.folder
deployment
adalah tempatrsuite
akan menulis semua binari paket yang ditunjukkan dalamDESCRIPTION
file paket . Jadi, ini membuat, dengan sendirinya, Anda memproyeksikan waktu akros yang sepenuhnya dapat direproduksi.rsuite
dilengkapi dengan klien untuk semua sistem operasi. Saya sudah menguji semuanya. Tetapi Anda juga dapat menginstalnya sebagaiaddin
untuk RStudio.rsuite
juga memungkinkan Anda membangunconda
instalasi yang terisolasi di foldernya sendiriconda
. Ini bukan lingkungan tetapi instalasi Python fisik yang berasal dari Anaconda di mesin Anda. Ini bekerja bersama-sama dengan R'sSystemRequirements
, dari mana Anda dapat menginstal semua paket Python yang Anda inginkan, dari saluran conda yang Anda inginkan.Anda juga dapat membuat repositori lokal untuk menarik paket R saat Anda offline, atau ingin membuat semuanya lebih cepat.
Jika mau, Anda juga dapat membangun proyek R sebagai file zip dan membaginya dengan kolega. Ini akan berjalan, asalkan kolega Anda memiliki versi R yang sama diinstal.
Pilihan lain adalah membangun wadah seluruh proyek di Ubuntu, Debian, atau CentOS. Jadi, alih-alih berbagi file zip dengan build proyek Anda, Anda membagikan seluruh
Docker
kontainer dengan proyek Anda yang siap dijalankan.Saya telah banyak bereksperimen dengan
rsuite
mencari reproduktifitas penuh, dan menghindari tergantung pada paket yang diinstal di lingkungan global. Ini salah karena segera setelah Anda menginstal pembaruan paket, proyek, lebih sering daripada tidak, berhenti bekerja, khususnya paket-paket dengan panggilan yang sangat spesifik ke suatu fungsi dengan parameter tertentu.Hal pertama yang saya mulai coba adalah dengan
bookdown
ebooks. Saya tidak pernah cukup beruntung memiliki bookdown untuk bertahan dalam ujian waktu lebih dari enam bulan. Jadi, apa yang saya lakukan adalah mengonversi proyek bookdown asli untuk mengikutirsuite
kerangka kerja. Sekarang, saya tidak perlu khawatir tentang memperbarui lingkungan R global saya, karena proyek ini memiliki paket sendiri dalamdeployment
folder tersebut.Hal berikutnya yang saya lakukan adalah membuat proyek pembelajaran mesin tetapi di
rsuite
jalan. Master, mengatur proyek di atas, dan semua sub proyek dan paket berada di bawah kendali master. Ini benar-benar mengubah cara Anda berkode dengan R, membuat Anda lebih produktif.Setelah itu saya mulai bekerja di paket baru saya yang disebut
rTorch
. Ini mungkin, sebagian besar, karenarsuite
; itu membuat Anda berpikir dan menjadi besar.Salah satu nasihat. Belajar
rsuite
itu tidak mudah. Karena menghadirkan cara baru untuk membuat proyek R, rasanya sulit. Jangan kecewa pada upaya pertama, terus mendaki lereng sampai Anda berhasil. Ini membutuhkan pengetahuan lanjutan tentang sistem operasi Anda dan sistem file Anda.Saya berharap bahwa suatu hari
RStudio
memungkinkan kita untuk menghasilkan proyekrsuite
pengaturan seperti halnya dari menu. Itu akan luar biasa.Tautan:
Repo RSuite GitHUb
Bookdown r4ds
tutorial keras dan mengkilap
moderndive-book-rsuite
interpretable_ml-rsuite
IntroMachineLearningWithR-rsuite
clark-intro_ml-rsuite
hyndman-bookdown-rsuite
Statistical_rethinking-rsuite
fread-benchmarks-rsuite
dataviz-rsuite
retail-segmentation-h2o-tutorial
telco-customer-churn-tutorial
sclerotinia_rsuite
sumber
R OK untuk penggunaan interaktif dan skrip kecil, tapi saya tidak akan menggunakannya untuk program besar. Saya akan menggunakan bahasa umum untuk sebagian besar pemrograman dan membungkusnya dalam antarmuka R.
sumber
Rcpp
paket, termasuk kode C ++ dalam program R menjadi sangat mudah. Jadi menulis ulang bagian tertentu dari kode R dapat diintegrasikan ke dalam R dengan cukup mudah. Selain itu, kedatangan RStudio telah memperkenalkan IDE untuk R, meskipun mungkin belum sekuat Visual Studio.