คำแนะนำทั่วไปสำหรับการดีบักใน R


120

ฉันได้รับข้อผิดพลาดเมื่อใช้ฟังก์ชัน R ที่ฉันเขียน:

Warning messages:
1: glm.fit: algorithm did not converge 
2: glm.fit: algorithm did not converge 

สิ่งที่ฉันทำ:

  1. ก้าวผ่านฟังก์ชั่น
  2. glm.fitการเพิ่มการพิมพ์เพื่อหาสิ่งที่สายข้อผิดพลาดเกิดขึ้นแสดงให้เห็นทั้งสองฟังก์ชั่นที่ไม่ควรใช้ พวกเขาเป็นและwindow()save()

วิธีการทั่วไปของฉันรวมถึงการเพิ่มprintและstopคำสั่งและการดำเนินการตามฟังก์ชันทีละบรรทัดจนกระทั่งฉันสามารถค้นหาข้อยกเว้นได้

อย่างไรก็ตามไม่ชัดเจนสำหรับฉันที่ใช้เทคนิคเหล่านั้นซึ่งข้อผิดพลาดนี้มาจากโค้ด glm.fitผมไม่ได้บางอย่างที่ฟังก์ชั่นภายในรหัสขึ้นอยู่กับ ฉันจะวินิจฉัยปัญหานี้ได้อย่างไร


5
ตรวจสอบหน้าของ Duncan Murdoch เกี่ยวกับการแก้จุดบกพร่องใน R
Rob Hyndman

10
ตกลงฉันจะระบุชัดเจน: ว่าเป็นคำเตือนที่ไม่ได้เป็นข้อผิดพลาด
Gavin Simpson

10
@ gavin-simpson ฉันไม่รู้ว่ามีความแตกต่างทางเทคนิคขอบคุณที่ชี้ให้เห็น แต่สุดท้ายมันบ่งบอกว่าหน้าที่การทำงานของฉันก่อนหน้านี้ผิดปกติ
David LeBauer

11
@David +1 สำหรับ "... ฟังก์ชันการทำงานก่อนหน้านี้ของฉันทำงานผิดปกติ"
Joshua Ulrich

5
@ เดวิด: เป็น ps ของคุณ สิ่งนี้จะเพิ่มมิติให้กับคำถามที่จะพลาดไปโดยไม่มีตัวอย่าง คือจะทำอย่างไรให้ R เข้าสู่โหมดดีบั๊กเมื่อมีการสร้างคำเตือนเท่านั้น? options(warn = 2)หากคุณมีเหลือรายละเอียดออกนี้เราต้องการทั้งหมดที่ไม่ได้ชี้ให้คุณ ดังนั้นในกรณีนี้รายละเอียดจึงจำเป็นต่อการตอบคำถามทั่วไปของคุณ +1 จากฉัน
Gavin Simpson

คำตอบ:


167

ฉันจะบอกว่าการดีบั๊กเป็นรูปแบบศิลปะดังนั้นจึงไม่มีสัญลักษณ์แสดงหัวข้อย่อยสีเงินที่ชัดเจน มีกลยุทธ์ที่ดีสำหรับการแก้ไขข้อบกพร่องในภาษาใด ๆ และใช้ที่นี่ด้วย (เช่นอ่านบทความดีๆนี้ ) ตัวอย่างเช่นสิ่งแรกคือการทำให้เกิดปัญหาขึ้นอีกครั้ง ... หากคุณไม่สามารถทำได้คุณจะต้องได้รับข้อมูลเพิ่มเติม (เช่นการบันทึก) เมื่อคุณสร้างซ้ำได้แล้วคุณต้องลดขนาดลงไปที่แหล่งที่มา

แทนที่จะเป็น "เคล็ดลับ" ฉันจะบอกว่าฉันมีกิจวัตรการดีบักที่ชอบ:

  1. เมื่อเกิดข้อผิดพลาดสิ่งแรกที่ฉันมักจะทำคือดูที่การติดตามสแต็กโดยการเรียกtraceback(): ที่แสดงให้คุณเห็นว่าเกิดข้อผิดพลาดที่ใดซึ่งมีประโยชน์อย่างยิ่งหากคุณมีฟังก์ชันซ้อนกันหลายฟังก์ชัน
  2. ต่อไปฉันจะตั้งoptions(error=recover); สิ่งนี้จะเปลี่ยนเข้าสู่โหมดเบราว์เซอร์ทันทีที่เกิดข้อผิดพลาดดังนั้นคุณสามารถเรียกดูพื้นที่ทำงานจากที่นั่นได้
  3. หากฉันยังมีข้อมูลไม่เพียงพอฉันมักจะใช้debug()ฟังก์ชันและขั้นตอนตามสคริปต์ทีละบรรทัด

เคล็ดลับใหม่ที่ดีที่สุดใน R 2.10 (เมื่อทำงานกับไฟล์สคริปต์) คือการใช้ฟังก์ชัน findLineNum()andsetBreakpoint()

ตามความเห็นสุดท้าย: ขึ้นอยู่กับข้อผิดพลาดการตั้งค่าtry()หรือtryCatch()คำสั่งเกี่ยวกับการเรียกใช้ฟังก์ชันภายนอก (โดยเฉพาะเมื่อจัดการกับคลาส S4) ซึ่งบางครั้งจะให้ข้อมูลเพิ่มเติมและยังช่วยให้คุณสามารถควบคุมวิธีจัดการข้อผิดพลาดในขณะทำงานได้มากขึ้น

คำถามที่เกี่ยวข้องเหล่านี้มีคำแนะนำมากมาย:


8
คุณสามารถเพิ่ม debugonce () เพื่อ debug () ได้เช่นกัน
Joris Meys

2
แม้ว่าจะไม่ได้มีประโยชน์เพียงอย่างเดียวเมื่อทำการดีบั๊ก แต่การแก้ไข (df1) จะเปิดตัวแก้ไขกราฟิก R พร้อมกับเฟรมข้อมูล df1 ที่โหลดไว้ซึ่งคุณสามารถแก้ไขได้ทันทีหรือเพียงแค่เหลือบมอง
Dmitrii I.

การดีบักใน R ดูเหมือนจะยากมากเช่นไม่มีวิธีง่ายๆในการดูบรรทัดคำเตือน
TMS

browser()เมื่อมีข้อผิดพลาดที่ไม่ทำให้เกิดคำเตือน / ข้อผิดพลาด (เครดิต: Roman Luštrikในหน้านี้) เครื่องมืออื่น ๆ เช่นbrowser()?
PatrickT

38

คำแนะนำที่ดีที่สุดที่ฉันเคยเห็นคือ:

http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf

มีใครเห็นด้วย / ไม่เห็นด้วย?


คำแนะนำอย่างละเอียด - อธิบายถึงเครื่องมือสำคัญที่รวมอยู่ใน R core: debug (), traceback () และ recover ()
Sharpie

32

ในฐานะที่ได้รับการชี้ให้เห็นกับผมในคำถามอื่น , Rprof()และsummaryRprof()เป็นเครื่องมือที่ดีที่จะหาชิ้นส่วนช้าของโปรแกรมของคุณที่อาจได้รับประโยชน์จากการเร่งขึ้นหรือย้ายไปยัง C / C ++ การดำเนินงาน ซึ่งอาจมีผลมากกว่านี้หากคุณกำลังทำงานจำลองหรือกิจกรรมการประมวลผลหรือกิจกรรมที่ต้องใช้ข้อมูลมาก profrแพคเกจสามารถช่วยให้การแสดงผล

ฉันกำลังเรียนรู้เกี่ยวกับการแก้ไขข้อบกพร่องดังนั้นข้อเสนอแนะอื่นจากเธรดอื่น :

  • ตั้งค่าoptions(warn=2)ให้ปฏิบัติต่อคำเตือนเช่นข้อผิดพลาด

นอกจากนี้คุณยังสามารถใช้optionsเพื่อทำให้คุณตกอยู่ในความร้อนแรงของการกระทำเมื่อเกิดข้อผิดพลาดหรือคำเตือนโดยใช้ฟังก์ชันการดีบักที่คุณชื่นชอบ ตัวอย่างเช่น:

  • ตั้งค่าoptions(error=recover)ให้ทำงานrecover()เมื่อเกิดข้อผิดพลาดดังที่ Shane กล่าวไว้ (และตามที่ระบุไว้ในคู่มือการดีบัก Rหรือฟังก์ชันอื่น ๆ ที่มีประโยชน์ที่คุณจะพบว่ามีประโยชน์ในการเรียกใช้

และอีกสองวิธีจากหนึ่งในลิงค์ของ @ Shane :

  • รวมการเรียกใช้ฟังก์ชันภายในด้วยtry()เพื่อส่งคืนข้อมูลเพิ่มเติม
  • สำหรับ * ใช้ฟังก์ชันให้ใช้.inform=TRUE(จากแพ็คเกจ plyr) เป็นตัวเลือกสำหรับคำสั่งใช้

@JoshuaUlrich ยังชี้ให้เห็นถึงวิธีที่เป็นระเบียบในการใช้ความสามารถตามเงื่อนไขของbrowser()คำสั่งคลาสสิกเพื่อเปิด / ปิดการดีบัก:

  • ใส่ฟังก์ชันที่คุณอาจต้องการแก้ไขข้อบกพร่อง browser(expr=isTRUE(getOption("myDebug")))
  • และตั้งค่าตัวเลือกส่วนกลางโดย options(myDebug=TRUE)
  • คุณสามารถปิดการโทรของเบราว์เซอร์: myBrowse <- browser(expr=isTRUE(getOption("myDebug")))แล้วโทรด้วยmyBrowse()เนื่องจากใช้ globals

จากนั้นมีฟังก์ชั่นใหม่ที่มีอยู่ใน R 2.10:

  • findLineNum()รับชื่อไฟล์ต้นฉบับและหมายเลขบรรทัดและส่งคืนฟังก์ชันและสภาพแวดล้อม ดูเหมือนว่าจะมีประโยชน์เมื่อคุณsource()เป็นไฟล์. R และส่งกลับข้อผิดพลาดที่บรรทัด #n แต่คุณต้องรู้ว่าฟังก์ชันใดอยู่ที่บรรทัด #n
  • setBreakpoint() ใช้ชื่อไฟล์ต้นฉบับและหมายเลขบรรทัดและตั้งค่าเบรกพอยต์ที่นั่น

codetoolsแพคเกจและโดยเฉพาะอย่างยิ่งของcheckUsageฟังก์ชั่นจะเป็นประโยชน์อย่างยิ่งในการได้อย่างรวดเร็วยกขึ้นไวยากรณ์และข้อผิดพลาดโวหารที่เรียบเรียงโดยทั่วไปแล้วจะรายงาน (ชาวบ้านที่ไม่ได้ใช้ไม่ได้กำหนดฟังก์ชั่นระดับโลกและตัวแปรการจับคู่โต้แย้งบางส่วนและอื่น ๆ )

setBreakpoint()trace()เป็นมิตรกับผู้ใช้มากขึ้นสิ้นหน้าไป รายละเอียดเกี่ยวกับ internals ของวิธีการทำงานนี้มีอยู่ในบทความล่าสุด R วารสาร

หากคุณกำลังพยายามดีบักแพ็กเกจของผู้อื่นเมื่อคุณพบปัญหาแล้วคุณสามารถเขียนฟังก์ชันของพวกเขามากเกินไปด้วยfixInNamespaceและassignInNamespaceแต่อย่าใช้สิ่งนี้ในรหัสการผลิต

สิ่งนี้ไม่ควรกีดกันเครื่องมือดีบัก R มาตรฐานที่พยายามและเป็นจริงซึ่งบางตัวอยู่เหนือและอื่น ๆ ที่ไม่ใช่ โดยเฉพาะอย่างยิ่งเครื่องมือดีบักหลังการชันสูตรมีประโยชน์เมื่อคุณมีโค้ดจำนวนมากที่ใช้เวลานานซึ่งคุณไม่ต้องการเรียกใช้ซ้ำ

สุดท้ายสำหรับปัญหาที่ยุ่งยากซึ่งดูเหมือนจะไม่มีข้อความแสดงข้อผิดพลาดคุณสามารถใช้options(error=dump.frames)ตามรายละเอียดในคำถามนี้: ข้อผิดพลาดโดยไม่มีข้อผิดพลาดถูกโยน


1
+1 สำหรับงานทั้งหมดที่คุณรวบรวมไว้ในการรวมคำถามเหล่านี้ให้เป็นหนึ่งเดียวแล้วเปิดต่อไป!
GSee

29

ในบางจุดglm.fitกำลังถูกเรียกตัว นั่นหมายความว่าหนึ่งในฟังก์ชั่นที่คุณโทรหรือหนึ่งในฟังก์ชั่นที่เรียกว่าโดยฟังก์ชั่นเหล่านั้นจะใช้อย่างใดอย่างหนึ่ง,glmglm.fit

นอกจากนี้ที่ฉันพูดถึงในความคิดเห็นด้านบนนั่นคือคำเตือนไม่ใช่ข้อผิดพลาดซึ่งสร้างความแตกต่างอย่างมาก คุณไม่สามารถเรียกใช้เครื่องมือดีบักของ R ใด ๆ จากคำเตือน (ด้วยตัวเลือกเริ่มต้นก่อนที่จะมีคนบอกว่าฉันผิด ;-)

หากเราเปลี่ยนตัวเลือกเพื่อเปลี่ยนคำเตือนให้เป็นข้อผิดพลาดเราสามารถเริ่มใช้เครื่องมือดีบั๊กของ R ได้ จาก?optionsเรามี:

 ‘warn’: sets the handling of warning messages.  If ‘warn’ is
      negative all warnings are ignored.  If ‘warn’ is zero (the
      default) warnings are stored until the top-level function
      returns.  If fewer than 10 warnings were signalled they will
      be printed otherwise a message saying how many (max 50) were
      signalled.  An object called ‘last.warning’ is created and
      can be printed through the function ‘warnings’.  If ‘warn’ is
      one, warnings are printed as they occur.  If ‘warn’ is two or
      larger all warnings are turned into errors.

ดังนั้นถ้าคุณวิ่ง

options(warn = 2)

จากนั้นเรียกใช้รหัสของคุณ R จะแสดงข้อผิดพลาด เมื่อถึงจุดนั้นคุณสามารถวิ่งได้

traceback()

เพื่อดูกลุ่มการโทร นี่คือตัวอย่าง

> options(warn = 2)
> foo <- function(x) bar(x + 2)
> bar <- function(y) warning("don't want to use 'y'!")
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!
> traceback()
7: doWithOneRestart(return(expr), restart)
6: withOneRestart(expr, restarts[[1L]])
5: withRestarts({
       .Internal(.signalCondition(simpleWarning(msg, call), msg, 
           call))
       .Internal(.dfltWarn(msg, call))
   }, muffleWarning = function() NULL)
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 
       2)))
3: warning("don't want to use 'y'!")
2: bar(x + 2)
1: foo(1)

คุณสามารถเพิกเฉยต่อเฟรมที่มีเครื่องหมาย4:และสูงกว่าได้ที่นี่ เราเห็นว่ามีการfooเรียกbarและbarสร้างคำเตือน ซึ่งจะแสดงให้คุณเห็นว่าฟังก์ชันใดกำลังเรียกglm.fitใช้

หากคุณต้องการแก้ไขจุดบกพร่องในตอนนี้เราสามารถเปลี่ยนไปใช้ตัวเลือกอื่นเพื่อบอกให้ R ป้อนดีบักเกอร์เมื่อพบข้อผิดพลาดและเมื่อเราทำข้อผิดพลาดคำเตือนเราจะได้รับดีบักเกอร์เมื่อคำเตือนเดิมถูกทริกเกอร์ เพื่อที่คุณควรเรียกใช้:

options(error = recover)

นี่คือตัวอย่าง:

> options(error = recover)
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!

Enter a frame number, or 0 to exit   

1: foo(1)
2: bar(x + 2)
3: warning("don't want to use 'y'!")
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 2)))
5: withRestarts({
6: withOneRestart(expr, restarts[[1]])
7: doWithOneRestart(return(expr), restart)

Selection:

จากนั้นคุณสามารถเข้าไปในเฟรมเหล่านั้นเพื่อดูว่าเกิดอะไรขึ้นเมื่อมีการเตือน

หากต้องการรีเซ็ตตัวเลือกข้างต้นเป็นค่าเริ่มต้นให้ป้อน

options(error = NULL, warn = 0)

สำหรับคำเตือนเฉพาะที่คุณอ้างมีความเป็นไปได้สูงที่คุณจะต้องอนุญาตให้มีการทำซ้ำเพิ่มเติมในโค้ด เมื่อคุณพบสิ่งที่เรียกglm.fitทำงานออกวิธีที่จะผ่านมันcontrolอาร์กิวเมนต์ใช้glm.control- ?glm.controlดู


4
คำตอบที่ดี ข้อสังเกตประการหนึ่งของการมองในแง่ร้ายคือข้อผิดพลาดในการบรรจบกันประเภทนี้มักเกิดขึ้นกับชุดข้อมูลที่ไม่เสถียร / ว่องไว (การแยกที่สมบูรณ์ ฯลฯ ) และหน้าต่างระหว่าง 'การรวมเข้ากันได้ดี' และ 'ไม่ใช่การบรรจบกัน แต่ไม่สามารถแก้ไขได้ด้วยจำนวนที่เพิ่มขึ้น ของการทำซ้ำ - ต้องการการเปลี่ยนแปลงที่รุนแรงมากขึ้น 'มักจะแคบ
Ben Bolker

3
Gavin ฉันเอาชนะคุณ 25 วินาที ฉันต้องการให้คุณลบคำตอบที่เป็นประโยชน์มากเกินไปและหยุดขโมยการโหวตของฉัน ;-)
Joshua Ulrich

@ เบ็นจุดดี. หากปัญหาของเดวิดคือการแยกจากกันการเพิ่มจำนวนการทำซ้ำก็ไม่น่าจะช่วยได้ แต่ก็ยังไม่สามารถรวมเข้าด้วยกันได้ เมื่อถึงจุดนั้นการดูค่าประมาณและข้อผิดพลาดมาตรฐานอาจบ่งชี้ว่ามีปัญหา ฉันยังคาดหวังว่าจะเห็นคำเตือนเกี่ยวกับค่าที่ติดตั้งเป็นตัวเลข 0 หรือ 1 หากการแยกหรือสิ่งที่คล้ายกันมีปัญหา หากการเพิ่มจำนวนการทำซ้ำไม่ช่วย David สามารถโพสต์ Q อื่นเพื่อขอความช่วยเหลือและฉันสามารถขโมย upvotes ของ @ Joshua ได้มากขึ้น ;-)
Gavin Simpson

1
@ โจชัวไม่มีทางเอาชนะเขาได้ ฉันหยุดนับคะแนนโหวตที่ฉันอาจแพ้เพราะเขา แต่อย่างไรก็ตามความช่วยเหลือที่เขาให้มานั้น ต้องหาช่องของตัวเองว่าคุณเอาชนะเขาได้ไหม ฉันขอแนะนำให้
โหวตเพิ่มคะแนน

1
Dammit @ ran2 นายทำลายความขี้ขลาดของฉันแผนชั่วร้ายที่จะยึดครองโลกมวาฮ่า !!!!
Gavin Simpson

21

ดังนั้นbrowser(), traceback()และdebug()เดินเข้าไปในบาร์ แต่trace()รออยู่ข้างนอกและช่วยให้มอเตอร์ทำงาน

การแทรกที่browserใดที่หนึ่งในฟังก์ชันของคุณการดำเนินการจะหยุดและรอการป้อนข้อมูลของคุณ คุณสามารถก้าวไปข้างหน้าโดยใช้n(หรือEnter) เรียกใช้กลุ่มทั้งหมด (การวนซ้ำ) ด้วยการcจบลูป / ฟังก์ชันปัจจุบันด้วยfหรือออกด้วยQ; ดู?browser.

ด้วยdebugคุณจะได้รับเอฟเฟกต์เช่นเดียวกับเบราว์เซอร์ แต่จะหยุดการทำงานของฟังก์ชันเมื่อเริ่มต้น ใช้ทางลัดเดียวกัน ฟังก์ชันนี้จะอยู่ในโหมด "ดีบัก" จนกว่าคุณจะปิดโดยใช้undebug(นั่นคือหลังจากdebug(foo)เรียกใช้ฟังก์ชันfooนี้จะเข้าสู่โหมด "แก้จุดบกพร่อง" ทุกครั้งจนกว่าคุณจะเรียกใช้undebug(foo))

อีกทางเลือกหนึ่งคือการdebugonceลบโหมด "ดีบัก" ออกจากฟังก์ชันหลังจากการประเมินครั้งถัดไป

traceback จะทำให้คุณมีขั้นตอนการทำงานของฟังก์ชันไปจนถึงจุดที่เกิดข้อผิดพลาด (ข้อผิดพลาดจริง)

คุณสามารถแทรกบิตรหัส (ฟังก์ชั่นที่กำหนดเอง IE) ในฟังก์ชั่นการใช้ตัวอย่างเช่นtrace browserสิ่งนี้มีประโยชน์สำหรับฟังก์ชั่นจากแพ็คเกจและคุณขี้เกียจเกินไปที่จะรับซอร์สโค้ดที่พับเก็บไว้อย่างดี


18

กลยุทธ์ทั่วไปของฉันดูเหมือนว่า:

  1. วิ่งtraceback()ไปดูเพื่อหาปัญหาที่ชัดเจน
  2. ตั้งค่าoptions(warn=2)ให้ปฏิบัติต่อคำเตือนเช่นข้อผิดพลาด
  3. ตั้งค่าoptions(error=recover)ให้เข้าสู่ call stack เมื่อเกิดข้อผิดพลาด

15

หลังจากทำตามขั้นตอนทั้งหมดที่แนะนำที่นี่ฉันเพิ่งได้เรียนรู้ว่าการตั้งค่า.verbose = TRUEในforeach()ยังให้ข้อมูลที่เป็นประโยชน์มากมาย โดยเฉพาะอย่างยิ่งforeach(.verbose=TRUE)แสดงให้เห็นว่ามีข้อผิดพลาดเกิดขึ้นภายในลูป foreach ในขณะที่traceback()ไม่ได้ดูภายในลูป foreach


13

ดีบักเกอร์ของ Mark Bravington ซึ่งมีให้ในแพ็คเกจdebugCRAN นั้นดีมากและค่อนข้างตรงไปตรงมา

library(debug);
mtrace(myfunction);
myfunction(a,b);
#... debugging, can query objects, step, skip, run, breakpoints etc..
qqq(); # quit the debugger only
mtrace.off(); # turn off debugging

โค้ดจะปรากฏขึ้นในหน้าต่าง Tk ที่ไฮไลต์เพื่อให้คุณสามารถดูว่าเกิดอะไรขึ้นและแน่นอนว่าคุณสามารถโทรหาคนอื่นได้mtrace()ในขณะที่อยู่ในฟังก์ชันอื่น

HTH


11

ฉันชอบคำตอบของ Gavin: ฉันไม่รู้เกี่ยวกับตัวเลือก (error = recover) ฉันยังชอบใช้แพ็คเกจ 'debug' ที่ให้ภาพในการก้าวผ่านโค้ดของคุณ

require(debug)
mtrace(foo)
foo(1)

ณ จุดนี้หน้าต่างดีบักแยกต่างหากที่แสดงฟังก์ชันของคุณโดยมีเส้นสีเหลืองแสดงตำแหน่งที่คุณอยู่ในโค้ด ในหน้าต่างหลักรหัสจะเข้าสู่โหมดดีบักและคุณสามารถกด Enter เพื่อก้าวผ่านโค้ด (และยังมีคำสั่งอื่น ๆ ด้วย) และตรวจสอบค่าตัวแปรเป็นต้นเส้นสีเหลืองในหน้าต่างดีบักจะเคลื่อนไปเรื่อย ๆ เพื่อแสดงตำแหน่ง คุณอยู่ในรหัส เมื่อเสร็จสิ้นการดีบักคุณสามารถปิดการติดตามด้วย:

mtrace.off()

5

จากคำตอบที่ฉันได้รับที่นี่คุณควรตรวจสอบการoptions(error=recover)ตั้งค่าอย่างแน่นอน เมื่อตั้งค่านี้เมื่อพบข้อผิดพลาดคุณจะเห็นข้อความบนคอนโซลคล้ายกับข้อความต่อไปนี้ ( tracebackเอาต์พุต):

> source(<my filename>)
Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

Enter a frame number, or 0 to exit   

1: source(<my filename>)
2: eval.with.vis(ei, envir)
3: eval.with.vis(expr, envir, enclos)
4: LinearParamSearch(data = dataset, y = data.frame(LGD = dataset$LGD10), data.names = data
5: LinearParamSearch.R#66: plot(x = x, y = y.data, xlab = names(y), ylab = data.names[i])
6: LinearParamSearch.R#66: plot.default(x = x, y = y.data, xlab = names(y), ylab = data.nam
7: LinearParamSearch.R#66: localWindow(xlim, ylim, log, asp, ...)
8: LinearParamSearch.R#66: plot.window(...)

Selection:

คุณสามารถเลือก "เฟรม" ที่จะเข้าสู่จุดใดได้ เมื่อคุณทำการเลือกคุณจะเข้าสู่browser()โหมด:

Selection: 4
Called from: stop(gettextf("replacement has %d rows, data has %d", N, n), 
    domain = NA)
Browse[1]> 

และคุณสามารถตรวจสอบสภาพแวดล้อมในขณะที่เกิดข้อผิดพลาดได้ เมื่อเสร็จแล้วพิมพ์cเพื่อนำคุณกลับไปที่เมนูการเลือกเฟรม เมื่อคุณทำเสร็จแล้วตามที่0แจ้งให้พิมพ์เพื่อออก


4

ฉันให้คำตอบนี้สำหรับคำถามล่าสุดแต่กำลังเพิ่มที่นี่เพื่อความสมบูรณ์

โดยส่วนตัวแล้วฉันมักจะไม่ใช้ฟังก์ชันในการดีบัก ฉันมักจะพบว่าสิ่งนี้ทำให้เกิดปัญหามากพอ ๆ กับการแก้ปัญหา นอกจากนี้มาจากพื้นหลัง Matlab ฉันชอบที่จะทำสิ่งนี้ได้ในสภาพแวดล้อมการพัฒนาแบบรวม (IDE) แทนที่จะทำในโค้ด การใช้ IDE ทำให้โค้ดของคุณสะอาดและเรียบง่าย

สำหรับ R ฉันใช้ IDE ที่เรียกว่า "RStudio" ( http://www.rstudio.com ) ซึ่งพร้อมใช้งานสำหรับ windows, mac และ linux และค่อนข้างใช้งานง่าย

เวอร์ชันของ Rstudio ตั้งแต่ประมาณตุลาคม 2013 (0.98ish?) มีความสามารถในการเพิ่มเบรกพอยต์ในสคริปต์และฟังก์ชัน: ทำได้โดยคลิกที่ขอบด้านซ้ายของไฟล์เพื่อเพิ่มเบรกพอยต์ คุณสามารถตั้งค่าเบรกพอยต์แล้วก้าวผ่านจากจุดนั้นไป คุณยังสามารถเข้าถึงข้อมูลทั้งหมดในสภาพแวดล้อมนั้นได้ดังนั้นคุณสามารถลองใช้คำสั่งต่างๆ

ดูรายละเอียดhttp://www.rstudio.com/ide/docs/debugging/overview หากคุณติดตั้ง Rstudio ไว้แล้วคุณอาจต้องอัปเกรดซึ่งเป็นคุณสมบัติที่ค่อนข้างใหม่ (ปลายปี 2013)

คุณอาจพบ IDE อื่น ๆ ที่มีฟังก์ชันการทำงานคล้ายกัน

เป็นที่ยอมรับหากเป็นฟังก์ชั่นในตัวคุณอาจต้องหันไปใช้คำแนะนำบางอย่างของบุคคลอื่นในการสนทนานี้ แต่ถ้าเป็นรหัสของคุณเองที่ต้องแก้ไขโซลูชันที่ใช้ IDE อาจเป็นเพียงสิ่งที่คุณต้องการ


1

เพื่อดีบักเมธอดคลาสอ้างอิงโดยไม่มีการอ้างอิงอินสแตนซ์

ClassName$trace(methodName, browser)

0

ผมเริ่มที่จะคิดว่าไม่พิมพ์หมายเลขสายข้อผิดพลาด - ความต้องการขั้นพื้นฐานที่สุด - จำแนกตาม DEFAILT- เป็นชนิดของเรื่องตลกในบางR / Rstudio วิธีเดียวที่เชื่อถือได้ที่ฉันพบเพื่อค้นหาว่ามีข้อผิดพลาดเกิดขึ้นคือใช้ความพยายามเพิ่มเติมในการเรียกย้อนกลับ()และดูบรรทัดบนสุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.