Saya mendapatkan kesalahan saat menggunakan fungsi R yang saya tulis:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
Apa yang telah aku lakukan:
- Telusuri fungsinya
- Menambahkan print untuk mengetahui di baris mana kesalahan terjadi menunjukkan dua fungsi yang tidak boleh digunakan
glm.fit
. Mereka adalahwindow()
dansave()
.
Pendekatan umum saya termasuk menambahkan print
dan stop
perintah, dan melangkah melalui baris fungsi demi baris sampai saya dapat menemukan pengecualian.
Namun, tidak jelas bagi saya menggunakan teknik-teknik dari mana kesalahan ini berasal dalam kode. Saya bahkan tidak yakin fungsi mana yang bergantung pada kode glm.fit
. Bagaimana cara saya mendiagnosis masalah ini?
options(warn = 2)
. Jadi dalam kasus ini, detail penting untuk menjawab pertanyaan umum Anda. +1 dari saya.Jawaban:
Saya akan mengatakan bahwa debugging adalah bentuk seni, jadi tidak ada peluru perak yang jelas. Ada strategi bagus untuk debugging dalam bahasa apapun, dan mereka juga berlaku di sini (mis. Baca artikel bagus ini ). Misalnya, hal pertama adalah mereproduksi masalah ... jika Anda tidak dapat melakukannya, maka Anda perlu mendapatkan lebih banyak informasi (misalnya dengan logging). Setelah Anda dapat mereproduksinya, Anda perlu menguranginya ke sumbernya.
Daripada "trik", saya akan mengatakan bahwa saya memiliki rutinitas debugging favorit:
traceback()
: yang menunjukkan tempat terjadinya kesalahan, yang sangat berguna jika Anda memiliki beberapa fungsi bersarang.options(error=recover)
; ini segera beralih ke mode browser di mana kesalahan terjadi, sehingga Anda dapat menjelajahi ruang kerja dari sana.debug()
fungsi tersebut dan menelusuri skrip baris demi baris.Trik baru terbaik di R 2.10 (saat bekerja dengan file skrip) adalah menggunakan
findLineNum()
dansetBreakpoint()
fungsi.Sebagai komentar terakhir: tergantung pada kesalahannya, juga sangat membantu untuk mengatur
try()
atautryCatch()
pernyataan seputar pemanggilan fungsi eksternal (terutama saat berhadapan dengan kelas S4). Itu terkadang akan memberikan lebih banyak informasi, dan itu juga memberi Anda lebih banyak kontrol atas bagaimana kesalahan ditangani pada waktu proses.Pertanyaan terkait ini memiliki banyak saran:
sumber
browser()
karena ketika ada kesalahan yang tidak memicu peringatan / kesalahan (kredit: Roman Luštrik di halaman ini). Ada alat lain sepertibrowser()
?Panduan terbaik yang pernah saya lihat sejauh ini adalah:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Ada yang setuju / tidak setuju?
sumber
Seperti yang ditunjukkan kepada saya di pertanyaan lain ,
Rprof()
dansummaryRprof()
merupakan alat yang bagus untuk menemukan bagian lambat dari program Anda yang mungkin mendapat manfaat dari mempercepat atau beralih ke implementasi C / C ++. Ini mungkin berlaku lebih jika Anda melakukan pekerjaan simulasi atau aktivitas komputasi atau data intensif lainnya. Theprofr
paket dapat membantu memvisualisasikan hasil.Saya sedang mempelajari sedikit tentang men-debug, jadi saran lain dari utas lain :
options(warn=2)
untuk memperlakukan peringatan seperti kesalahanAnda juga dapat menggunakan
options
untuk membawa Anda langsung ke dalam panasnya tindakan ketika kesalahan atau peringatan terjadi, menggunakan fungsi debugging favorit pilihan Anda. Misalnya:options(error=recover)
untuk berjalanrecover()
ketika terjadi kesalahan, seperti yang dicatat Shane (dan seperti yang didokumentasikan dalam panduan debugging R. Atau fungsi praktis lainnya yang menurut Anda berguna untuk dijalankan.Dan dua metode lain dari salah satu tautan @ Shane :
try()
untuk mengembalikan informasi lebih lanjut tentang itu..inform=TRUE
(dari paket plyr) sebagai opsi untuk perintah terapkan@JoshuaUlrich juga menunjukkan cara yang rapi dalam menggunakan kemampuan bersyarat dari
browser()
perintah klasik untuk mengaktifkan / menonaktifkan debugging:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
dan kemudian memanggil denganmyBrowse()
karena menggunakan global.Lalu ada fungsi baru yang tersedia di R 2.10:
findLineNum()
mengambil nama file sumber dan nomor baris dan mengembalikan fungsi dan lingkungan. Ini tampaknya berguna ketika Andasource()
memiliki file .R dan mengembalikan kesalahan pada baris #n, tetapi Anda perlu mengetahui fungsi apa yang terletak di baris #n.setBreakpoint()
mengambil nama file sumber dan nomor baris dan menetapkan breakpoint di sanaThe codetools paket, dan khususnya yang
checkUsage
fungsinya dapat sangat membantu dalam cepat mengambil sintaks dan kesalahan gaya yang kompilator biasanya akan melaporkan (penduduk setempat yang tidak terpakai, tidak terdefinisi fungsi global dan variabel, parsial pencocokan argumen, dan sebagainya).setBreakpoint()
adalah front-end yang lebih ramah penggunatrace()
. Detail tentang internal cara kerjanya tersedia di artikel R Journal terbaru .Jika Anda mencoba men-debug paket orang lain, setelah Anda menemukan masalahnya, Anda dapat menulis ulang fungsinya dengan
fixInNamespace
danassignInNamespace
, tetapi jangan gunakan ini dalam kode produksi.Semua ini tidak boleh menghalangi alat debugging R standar yang telah dicoba dan benar , beberapa di antaranya di atas dan yang lainnya tidak. Secara khusus, alat debugging post-mortem berguna ketika Anda memiliki banyak kode yang memakan waktu yang tidak ingin Anda jalankan kembali.
Akhirnya, untuk masalah rumit yang sepertinya tidak memunculkan pesan kesalahan, Anda dapat menggunakan
options(error=dump.frames)
seperti yang dijelaskan dalam pertanyaan ini: Kesalahan tanpa kesalahan dilemparsumber
Di beberapa titik,
glm.fit
sedang dipanggil. Itu berarti salah satu fungsi Anda menelepon atau salah satu fungsi yang disebut dengan fungsi-fungsi yang baik menggunakanglm
,glm.fit
.Juga, seperti yang saya sebutkan dalam komentar saya di atas, itu adalah peringatan, bukan kesalahan , yang membuat perbedaan besar. Anda tidak dapat memicu alat debugging R dari peringatan (dengan opsi default sebelum seseorang memberi tahu saya bahwa saya salah ;-).
Jika kita mengubah opsi untuk mengubah peringatan menjadi kesalahan maka kita dapat mulai menggunakan alat debugging R. Dari
?options
kami memiliki:Jadi jika Anda lari
lalu jalankan kode Anda, R akan memunculkan error. Pada titik mana, Anda bisa lari
untuk melihat tumpukan panggilan. Berikut ini contohnya.
Di sini Anda dapat mengabaikan bingkai yang ditandai
4:
dan lebih tinggi. Kami melihat yangfoo
dipanggilbar
dan itubar
menghasilkan peringatan. Itu akan menunjukkan kepada Anda fungsi mana yang memanggilglm.fit
.Jika Anda sekarang ingin men-debug ini, kita dapat beralih ke opsi lain untuk memberi tahu R untuk masuk ke debugger ketika menemui kesalahan, dan karena kita telah membuat kesalahan peringatan, kita akan mendapatkan debugger ketika peringatan asli dipicu. Untuk itu Anda harus menjalankan:
Berikut ini contohnya:
Anda kemudian dapat masuk ke salah satu bingkai tersebut untuk melihat apa yang terjadi saat peringatan dilemparkan.
Untuk mengatur ulang opsi di atas ke defaultnya, masukkan
Adapun peringatan khusus yang Anda kutip, sangat mungkin Anda perlu mengizinkan lebih banyak iterasi dalam kode. Setelah Anda menemukan apa yang memanggil
glm.fit
, cari tahu bagaimana menyampaikancontrol
argumen tersebut menggunakanglm.control
- lihat?glm.control
.sumber
Jadi
browser()
,traceback()
dandebug()
berjalanlah ke bar, tapitrace()
menunggu di luar dan teruskan motornya.Dengan memasukkan
browser
suatu tempat di fungsi Anda, eksekusi akan berhenti dan menunggu masukan Anda. Anda dapat bergerak maju menggunakan n(atau Enter), menjalankan seluruh potongan (iterasi) dengan c, menyelesaikan loop / fungsi saat ini dengan f, atau berhenti dengan Q; lihat?browser
.Dengan
debug
, Anda mendapatkan efek yang sama seperti browser, tetapi ini menghentikan eksekusi fungsi di awal. Pintasan yang sama berlaku. Fungsi ini akan berada dalam mode "debug" sampai Anda menonaktifkannya menggunakanundebug
(yaitu, setelahdebug(foo)
menjalankan fungsi tersebutfoo
akan memasuki mode "debug" setiap kali hingga Anda menjalankannyaundebug(foo)
).Alternatif yang lebih sementara adalah
debugonce
, yang akan menghapus mode "debug" dari fungsi setelah dievaluasi lagi.traceback
akan memberi Anda aliran eksekusi fungsi hingga ke tempat yang salah (kesalahan sebenarnya).Anda dapat memasukkan bit kode (mis. Fungsi kustom) dalam fungsi menggunakan
trace
, misalnyabrowser
. Ini berguna untuk fungsi dari paket dan Anda terlalu malas untuk mendapatkan kode sumber yang terlipat dengan baik.sumber
Strategi umum saya terlihat seperti:
traceback()
untuk melihat mencari masalah yang jelasoptions(warn=2)
untuk memperlakukan peringatan seperti kesalahanoptions(error=recover)
untuk masuk ke tumpukan panggilan saat terjadi kesalahansumber
Setelah melalui semua langkah yang disarankan di sini, saya baru mengetahui bahwa pengaturan
.verbose = TRUE
diforeach()
juga memberi saya banyak informasi berguna. Secara khususforeach(.verbose=TRUE)
menunjukkan persis di mana kesalahan terjadi di dalam loop foreach, sementaratraceback()
tidak melihat ke dalam loop foreach.sumber
Debugger Mark Bravington yang tersedia sebagai paket
debug
di CRAN sangat bagus dan sangat mudah.Kode tersebut muncul di jendela Tk yang disorot sehingga Anda dapat melihat apa yang terjadi dan, tentu saja, Anda dapat memanggil yang lain
mtrace()
saat berada dalam fungsi yang berbeda.HTH
sumber
Saya suka jawaban Gavin: Saya tidak tahu tentang opsi (error = memulihkan). Saya juga suka menggunakan paket 'debug' yang memberikan cara visual untuk menelusuri kode Anda.
Pada titik ini, ini akan membuka jendela debug terpisah yang menampilkan fungsi Anda, dengan garis kuning menunjukkan di mana Anda berada dalam kode. Di jendela utama kode memasuki mode debug, dan Anda dapat terus menekan enter untuk melangkah melalui kode (dan ada perintah lain juga), dan memeriksa nilai variabel, dll. Garis kuning di jendela debug terus bergerak untuk menunjukkan di mana Anda berada di dalam kode. Setelah selesai dengan debugging, Anda dapat mematikan pelacakan dengan:
sumber
Berdasarkan jawaban yang saya terima di sini , Anda pasti harus memeriksa
options(error=recover)
pengaturannya. Jika ini disetel, saat mengalami kesalahan, Anda akan melihat teks di konsol yang mirip dengan berikut (traceback
keluaran):Pada titik mana Anda dapat memilih "bingkai" mana yang akan dimasuki. Saat Anda membuat pilihan, Anda akan ditempatkan dalam
browser()
mode:Dan Anda dapat memeriksa lingkungan seperti saat terjadi kesalahan. Setelah selesai, ketik
c
untuk membawa Anda kembali ke menu pemilihan bingkai. Setelah selesai, seperti yang diberitahukan, ketik0
untuk keluar.sumber
Saya memberikan jawaban ini untuk pertanyaan yang lebih baru, tetapi saya menambahkannya di sini untuk kelengkapan.
Secara pribadi saya cenderung tidak menggunakan fungsi untuk men-debug. Saya sering menemukan bahwa ini menyebabkan masalah sebanyak yang dapat dipecahkan. Juga, datang dari latar belakang Matlab saya suka bisa melakukan ini dalam lingkungan pengembangan terintegrasi (IDE) daripada melakukan ini dalam kode. Menggunakan IDE membuat kode Anda tetap bersih dan sederhana.
Untuk R, saya menggunakan IDE bernama "RStudio" ( http://www.rstudio.com ), yang tersedia untuk windows, mac, dan linux dan cukup mudah digunakan.
Versi Rstudio sejak sekitar Oktober 2013 (0.98ish?) Memiliki kemampuan untuk menambahkan breakpoint dalam skrip dan fungsi: untuk melakukan ini, cukup klik pada margin kiri file untuk menambahkan breakpoint. Anda dapat mengatur breakpoint dan kemudian melanjutkan dari titik itu. Anda juga memiliki akses ke semua data di lingkungan itu, sehingga Anda dapat mencoba perintah.
Lihat http://www.rstudio.com/ide/docs/debugging/overview untuk detailnya. Jika Anda sudah menginstal Rstudio, Anda mungkin perlu memutakhirkan - ini adalah fitur yang relatif baru (akhir 2013).
Anda juga dapat menemukan IDE lain yang memiliki fungsi serupa.
Memang, jika itu adalah fungsi bawaan Anda mungkin harus menggunakan beberapa saran yang dibuat oleh orang lain dalam diskusi ini. Namun, jika kode Anda sendiri yang perlu diperbaiki, solusi berbasis IDE mungkin yang Anda butuhkan.
sumber
Untuk men-debug metode Kelas Referensi tanpa referensi instance
sumber
Saya mulai berpikir bahwa tidak mencetak nomor baris kesalahan - persyaratan yang paling dasar - OLEH DEFAILT- adalah semacam lelucon di R / Rstudio . Satu-satunya metode yang dapat diandalkan yang saya temukan untuk menemukan di mana kesalahan terjadi adalah dengan melakukan upaya tambahan dari calloing traceback () dan melihat baris teratas.
sumber