การควบคุมจำนวนหลักทศนิยมในเอาต์พุตการพิมพ์ใน R


110

มีตัวเลือกใน R เพื่อควบคุมการแสดงผลหลัก ตัวอย่างเช่น:

options(digits=10)

ควรให้ผลการคำนวณเป็นตัวเลข 10 หลักจนจบเซสชัน R ในไฟล์วิธีใช้ของ R นิยามสำหรับพารามิเตอร์หลักมีดังนี้:

หลัก: ควบคุมจำนวนหลักที่จะพิมพ์เมื่อพิมพ์ค่าตัวเลข เป็นการเสนอแนะเท่านั้น ค่าที่ถูกต้องคือ1 ... 22โดยมีค่าเริ่มต้น7

ดังนั้นจึงบอกว่านี่เป็นคำแนะนำเท่านั้น จะเป็นอย่างไรหากฉันต้องการแสดงตัวเลข 10 หลักเสมอไม่มากหรือน้อย?

คำถามที่สองของฉันคือถ้าฉันต้องการแสดงตัวเลขมากกว่า 22 หลักเช่นเพื่อการคำนวณที่แม่นยำยิ่งขึ้นเช่น 100 หลัก? เป็นไปได้ไหมกับฐาน R หรือฉันต้องการแพ็คเกจ / ฟังก์ชั่นเพิ่มเติมสำหรับสิ่งนั้น?

แก้ไข:ขอบคุณข้อเสนอแนะของ jmoy ฉันพยายามsprintf("%.100f",pi)และให้มัน

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

ซึ่งมีทศนิยม 48 ตำแหน่ง นี่คือขีด จำกัด สูงสุดที่ R สามารถจัดการได้หรือไม่?


5
เฉพาะ 15 หลักแรกของ pi เท่านั้นที่ถูกต้อง เปรียบเทียบกับความคุ้มค่าที่แท้จริงjoyofpi.com/pi.html
Richie Cotton

1
คุณถูก. ทำไม R ถึงต่างกัน?
Mehper C. Palavuzlar

4
ดูคำถามที่พบบ่อยเกี่ยวกับ R cran.r-project.org/doc/FAQ/…
Richie Cotton

2
Mehper: ผมคิดว่าคุณตีความการเป็นตัวแทนในการคำนวณของตัวเลขในอาร์คุณอาจต้องการที่จะอ่านen.wikipedia.org/wiki/Floating_point
เชน

จากการเปรียบเทียบ Python ก็เหมือนกันpython -c "import math; print(format(math.pi, '.100f'))"ทุกประการ: ลอง ผลลัพธ์คือpiทศนิยม 48 "จริง" ยัดด้วยศูนย์สำหรับ 52 หลักที่เหลือ
syntaxerror

คำตอบ:


49

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

สำหรับคำถามที่สองเนื่องจาก R ใช้เลขคณิตที่มีความแม่นยำ จำกัด คำตอบของคุณจึงไม่ถูกต้องเกินทศนิยม 15 หรือ 16 ตำแหน่งโดยทั่วไปจึงไม่จำเป็นต้องใช้มากกว่านี้ GMPและRCDDแพคเกจการจัดการกับความแม่นยำทางคณิตศาสตร์หลาย ๆ (ผ่าน interace ไปยังห้องสมุด GMP) แต่นี้เป็นส่วนใหญ่ที่เกี่ยวข้องกับจำนวนเต็มขนาดใหญ่มากกว่าที่อื่น ๆ ตำแหน่งทศนิยมสำหรับคู่ของคุณ

MathematicaหรือMapleจะช่วยให้คุณสามารถกำหนดตำแหน่งทศนิยมได้มากเท่าที่ใจต้องการ

แก้ไข:
การคิดถึงความแตกต่างระหว่างตำแหน่งทศนิยมและตัวเลขที่สำคัญอาจเป็นประโยชน์ หากคุณกำลังทำการทดสอบทางสถิติที่อาศัยความแตกต่างนอกเหนือจากตัวเลขที่มีนัยสำคัญอันดับที่ 15 การวิเคราะห์ของคุณนั้นแทบจะเป็นขยะ

ในทางกลับกันถ้าคุณแค่จัดการกับตัวเลขที่น้อยมากนั่นก็เป็นปัญหาน้อยกว่าเนื่องจาก R สามารถจัดการกับตัวเลขได้น้อยถึง.Machine$double.xmin(โดยปกติคือ 2e-308)

เปรียบเทียบการวิเคราะห์ทั้งสองนี้

x1 <- rnorm(50, 1, 1e-15)
y1 <- rnorm(50, 1 + 1e-15, 1e-15)
t.test(x1, y1)  #Should throw an error

x2 <- rnorm(50, 0, 1e-15)
y2 <- rnorm(50, 1e-15, 1e-15)
t.test(x2, y2)  #ok

ในกรณีแรกความแตกต่างระหว่างตัวเลขจะเกิดขึ้นหลังจากตัวเลขที่มีนัยสำคัญจำนวนมากเท่านั้นดังนั้นข้อมูลจึง "เกือบคงที่" ในกรณีที่สองแม้ว่าขนาดของความแตกต่างระหว่างตัวเลขจะเท่ากัน แต่เมื่อเทียบกับขนาดของตัวเลขก็มีขนาดใหญ่


ดังที่กล่าวไว้ใน e3bo คุณสามารถใช้ตัวเลขทศนิยมที่มีความแม่นยำหลายจุดโดยใช้Rmpfrแพ็คเกจ

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

สิ่งเหล่านี้ช้ากว่าและใช้หน่วยความจำมากขึ้นกว่าnumericเวกเตอร์ปกติ (ความแม่นยำสองเท่า) แต่จะมีประโยชน์หากคุณมีปัญหาที่มีเงื่อนไขไม่ดีหรืออัลกอริทึมที่ไม่เสถียร


4
ตามที่แสดงหน้าRwiki แพคเกจ Rmpfrช่วยให้สามารถคำนวณเลขคณิตทศนิยมที่มีความแม่นยำสูงใน R
e3bo

แต่ Rmpfr สามารถใช้กับแพ็คเกจ R ใด ๆ เพื่อปรับปรุงความแม่นยำได้หรือไม่? หรือสามารถใช้เฉพาะฟังก์ชันที่เข้ารหัสไว้ภายในเท่านั้น?
กัน

2
ฉันคิดเพียงว่า "หากคุณกำลังทำการทดสอบทางสถิติที่อาศัยความแตกต่างนอกเหนือจากตัวเลขที่มีนัยสำคัญอันดับ 15 การวิเคราะห์ของคุณก็แทบจะเป็นขยะแน่นอน" แต่ฉันสงสัยว่าจำนวนหลักจะเป็นเท่าใดซึ่งฉันจะสรุปได้ว่ามันเป็นขยะและฉันคิดว่า 5 แต่ฉันยินดีที่จะแก้ไข
PatrickT

46

หากคุณผลิตผลผลิตทั้งหมดด้วยตัวคุณเองคุณสามารถใช้sprintf()เช่น

> sprintf("%.10f",0.25)
[1] "0.2500000000"

ระบุว่าคุณต้องการจัดรูปแบบตัวเลขทศนิยมสิบจุด (ใน%.10fรูปแบบfคือ.10ทศนิยมและระบุทศนิยมสิบตำแหน่ง)

ฉันไม่รู้วิธีบังคับให้ฟังก์ชันระดับสูงกว่าของ R พิมพ์ตัวเลขที่แน่นอน

การแสดงตัวเลข 100 หลักไม่สมเหตุสมผลหากคุณกำลังพิมพ์ตัวเลขปกติของ R เนื่องจากความแม่นยำที่ดีที่สุดที่คุณจะได้รับจากการใช้คู่ 64 บิตคือทศนิยม 16 หลัก (ดูที่. Machine $ double.eps ในระบบของคุณ) ตัวเลขที่เหลือจะเป็นขยะ


จริงๆแล้วการทดสอบไคสแควร์พิเศษบางอย่างที่ฉันใช้นั้นต้องการทศนิยมหลายร้อยเพื่อให้ได้ผลลัพธ์ที่แม่นยำ นอกจากนี้ pi ยังมีทศนิยมหลายพันตำแหน่ง นั่นเป็นเหตุผลที่ฉันสงสัยเกี่ยวกับตัวเลข 100 หลักขึ้นไป
Mehper C. Palavuzlar

14
pi มีทศนิยมไม่สิ้นสุด นั่นไม่ได้หมายความว่าคอมพิวเตอร์สามารถจัดเก็บได้
เชน

ฉันเดาว่านี่เป็นสถานการณ์ที่ Mathematica เหนือกว่า R.
skan

1
@skan คุณคิดว่า Mathematica เก็บทศนิยมได้ไม่ จำกัด หรือไม่?
Gregor Thomas

@ เกรเกอร์ไม่แน่นอน แต่คุณสามารถตัวเลขได้มากเท่าที่หน่วยความจำของคุณจะช่วยให้คุณได้
กัน

1

อีกวิธีหนึ่งที่สามารถควบคุมจำนวนทศนิยมที่จะพิมพ์ตามความต้องการ (หากคุณไม่ต้องการพิมพ์ศูนย์ซ้ำซ้อน)

ตัวอย่างเช่นหากคุณมีเวกเตอร์เป็นelementsและต้องการได้รับsumจาก เวกเตอร์

elements <- c(-1e-05, -2e-04, -3e-03, -4e-02, -5e-01, -6e+00, -7e+01, -8e+02)
sum(elements)
## -876.5432

เห็นได้ชัดว่าดิจิทัลสุดท้ายที่1ถูกตัดทอนผลลัพธ์ที่ดีควรเป็น-876.54321แต่หากตั้งค่าเป็นตัวเลือกทศนิยมการพิมพ์คงที่เช่นsprintf("%.10f", sum(elements))ศูนย์ซ้ำซ้อนจะสร้างเป็น-876.5432100000

ทำตามบทช่วยสอนที่นี่: การพิมพ์เลขฐานสิบหากสามารถระบุจำนวนทศนิยมในตัวเลขที่แน่นอนเช่นในที่-876.54321นี้มีทศนิยม 5 หลักที่ต้องพิมพ์จากนั้นเราสามารถตั้งค่าพารามิเตอร์สำหรับformatฟังก์ชันได้ดังนี้:

decimal_length <- 5
formatC(sum(elements), format = "f", digits = decimal_length)
## -876.54321

เราสามารถเปลี่ยนแปลงdecimal_lengthตามการสืบค้นแต่ละครั้งเพื่อให้สามารถตอบสนองความต้องการการพิมพ์ทศนิยมที่แตกต่างกันได้

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