การจัดรูปแบบตำแหน่งทศนิยมใน R


264

ฉันมีตัวเลขตัวอย่างเช่น 1.128347132904321674821 ที่ฉันต้องการแสดงเป็นทศนิยมสองตำแหน่งเท่านั้นเมื่อส่งออกไปยังหน้าจอ (หรือเขียนลงไฟล์) เราจะทำอย่างนั้นได้อย่างไร?

x <- 1.128347132904321674821

แก้ไข:

การใช้:

options(digits=2)

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

-

คำตอบ: รอบ (x, ตัวเลข = 2)


1
คำถามที่เกี่ยวข้อง: stackoverflow.com/questions/2287616/…
Shane

หากใช้ตัวเลือก (digit = 4) นั่นไม่ได้ จำกัด การคำนวณไว้ที่ 4 หลักใช่ไหม? ในกรณีนั้นมันจะทำให้โปรแกรมมีความแม่นยำน้อยลง มันมีผลต่อหมายเลขเมื่อพิมพ์ถูกต้องหรือไม่
MikeZ

controls the number of digits to print when printing numeric values. It is a suggestion only. Valid values are 1...22 with default 7. See the note in print.default about values greater than 15.จากตัวเลือกมันมีผลต่อการส่งออกเท่านั้น
Brandon Bertelsen

โปรดทราบว่าround(23, digits=2)จะพิมพ์และไม่ได้23 23.00หากคุณต้องการหลังให้ลองstackoverflow.com/a/12135122/180892
Jeromy Anglim

4
@ PaulHurleyuk ฉันคิดว่ามันเป็นแนวปฏิบัติที่ดีในการเขียนโปรแกรมเพื่อใช้จำนวนไลบรารีน้อยที่สุดเท่าที่จะเป็นไปได้ คนที่ใช้ไลบรารี่ที่แตกต่างกันสำหรับความต้องการที่ไม่สำคัญมักจะจบลงด้วยความยุ่งเหยิงไฟล์ขนาดใหญ่ปัญหาเกี่ยวกับการพกพาเป็นต้น
Rodrigo

คำตอบ:


381

พื้นหลัง:คำตอบบางข้อเสนอแนะในหน้านี้ (เช่นsignif, options(digits=...)) ไม่รับประกันว่าจำนวนที่แน่นอนของทศนิยมจะแสดงจำนวนข้อ ฉันคิดว่านี่เป็นคุณสมบัติการออกแบบใน R โดยวิธีปฏิบัติทางวิทยาศาสตร์ที่ดีเกี่ยวข้องกับการแสดงตัวเลขจำนวนหนึ่งตามหลักการของ " ตัวเลขสำคัญ " อย่างไรก็ตามในหลายโดเมน (เช่นรูปแบบ APAรายงานธุรกิจ) ข้อกำหนดการจัดรูปแบบกำหนดให้แสดงตำแหน่งทศนิยมจำนวนหนึ่ง สิ่งนี้มักจะทำเพื่อความมั่นคงและวัตถุประสงค์มาตรฐานแทนที่จะเกี่ยวข้องกับตัวเลขที่มีนัยสำคัญ

วิธีแก้ปัญหา :

xแสดงให้เห็นว่ารหัสต่อทศนิยมสองตำแหน่งหมายเลข

format(round(x, 2), nsmall = 2)

ตัวอย่างเช่น:

format(round(1.20, 2), nsmall = 2)
# [1] "1.20"
format(round(1, 2), nsmall = 2)
# [1] "1.00"
format(round(1.1234, 2), nsmall = 2)
# [1] "1.12"

ฟังก์ชั่นทั่วไปที่มากขึ้นมีดังต่อไปนี้โดยที่xเป็นจำนวนและkเป็นจำนวนทศนิยมที่จะแสดง trimwsลบช่องว่างนำหน้าซึ่งอาจเป็นประโยชน์หากคุณมีเวกเตอร์ของตัวเลข

specify_decimal <- function(x, k) trimws(format(round(x, k), nsmall=k))

เช่น,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"

4
+1 เฉพาะคำตอบที่ใช้ได้กับฉันพิมพ์อย่างถูกต้อง0.0001เป็น0.00
ThomasH

7
มันรบกวนฉันอยู่เสมอว่าฟังก์ชั่นชอบformat()และprettyNum()แปลงตัวเลขเป็นตัวละครอย่างไร คุณจะจัดการเรื่องนี้อย่างไร
Waldir Leoncio

คำพูดที่ปรากฏมีอะไรบ้าง
2560

2
@ JeromyAnglim ฉันทราบว่าวิธีการแก้ปัญหาดังกล่าวมีข้อเสียขอบกรณีที่เป็นไปได้ของการกำหนดจำนวนตัวอักษรในด้านหน้าของทศนิยมเช่น format(c(10, 1), nsmall=1)อัตราผลตอบแทน"10.0" " 1.0"(ทราบพื้นที่ชั้นนำในด้านหน้าของ 1.0 ในขณะที่sprintf()ฟังก์ชั่นดูเหมือนจะรับประกันการจัดรูปแบบ ทั้งสองด้านของทศนิยมเช่นsprintf(c(10,1), fmt = '%#.1f')ได้รับกำจัดของพื้นที่ที่น่ารำคาญชั้นนำที่และผลตอบแทน"10.0" "1.0".
นิโคลัสรีค G

1
ช่องว่างนำหน้าเป็นคุณสมบัติที่ออกแบบมาเพื่อจัดตำแหน่งจุดทศนิยมเมื่อผลลัพธ์ของการformatใช้ในคอลัมน์
ผู้อยู่อาศัย

34

คุณสามารถจัดรูปแบบตัวเลขพูดxได้ถึงตำแหน่งทศนิยมตามที่คุณต้องการ นี่xคือตัวเลขที่มีทศนิยมหลายตำแหน่ง สมมติว่าเราต้องการแสดงทศนิยม 8 หลักของตัวเลขนี้:

x = 1111111234.6547389758965789345
y = formatC(x, digits = 8, format = "f")
# [1] "1111111234.65473890"

ที่นี่format="f"ให้ตัวเลขลอยตัวในทศนิยมตามปกติพูด xxx.xxx และdigitsระบุจำนวนของตัวเลข ในทางตรงกันข้ามหากคุณต้องการให้จำนวนเต็มที่แสดงคุณจะใช้format="d"(เหมือนsprintf)


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

พวกคุณคนใดสามารถช่วยได้ในเรื่องนี้? stackoverflow.com/q/53279593/5224236
gpier

24

คุณสามารถลองแพ็คเกจของฉันจัดรูปแบบได้

> # devtools::install_github("renkun-ken/formattable")
> library(formattable)
> x <- formattable(1.128347132904321674821, digits = 2, format = "f")
> x
[1] 1.13

สิ่งที่ดีxคือยังคงเป็นเวกเตอร์ที่เป็นตัวเลขและคุณสามารถทำการคำนวณเพิ่มเติมด้วยการจัดรูปแบบเดียวกัน

> x + 1
[1] 2.13

ยิ่งไปกว่านั้นตัวเลขจะไม่สูญหายคุณสามารถจัดรูปแบบตัวเลขใหม่ได้ตลอดเวลา :)

> formattable(x, digits = 6, format = "f")
[1] 1.128347

ทิ่มแทงตัวเล็ก ๆ ตัวหนึ่งชักฉันทั้งเช้า ด้วยเหตุผลบางอย่าง R จะปัดเศษการแสดงผลสำหรับบางคอลัมน์เท่านั้น ฉันต้องการแก้ไขนี้เนื่องจากฉันต้องทำการคำนวณในคอลัมน์เหล่านั้นด้วย วิธีนี้ใช้ได้ผล ขอบคุณมาก!
thethakuri

ฉันชอบฟอร์แมตได้มากกว่าฟังก์ชั่น baseR ใด ๆ ข้อได้เปรียบที่ใหญ่ที่สุดจะรักษาตัวแปรเป็นตัวเลข
Lazarus Thurston

22

สำหรับตำแหน่งทศนิยม 2 ตำแหน่งสมมติว่าคุณต้องการเก็บค่าศูนย์ต่อท้าย

sprintf(5.5, fmt = '%#.2f')

ซึ่งจะช่วยให้

[1] "5.50"

เนื่องจาก @mpag ระบุไว้ด้านล่างดูเหมือนว่า R บางครั้งอาจให้ค่าที่ไม่คาดคิดกับวิธีนี้และวิธีการปัดเช่น sprintf (5.5550, fmt = '% #. 2f') ให้ 5.55 ไม่ใช่ 5.56


1
อย่างไรก็ตามแม้ว่า sprintf ปัดเศษ sprintf (5.5550, fmt = '% #. 2f') ให้ผลลัพธ์ที่ไม่คาดคิดเล็กน้อย: 5.55 sprintf (5.555000000001, fmt = '% #. 2f') ให้ 5.56 สิ่งนี้ดูเหมือนจะเป็น "ปัญหา" ทั่วไปที่มีการปัดเศษใน R เนื่องจากวิธีการปัดเศษ nsmall ก็ให้ผลเหมือนกัน
mpag

ขอบคุณ @mpag ฉันไม่รู้เลยว่า R ต่อสู้กับการปัดเศษบนขอบเขตฉันแค่ลองด้วย 5.565 ซึ่งจะวนขึ้นในขณะที่ 5.545 รอบ ฉันเดาว่ามันเป็นวิธีที่พวกเขาจัดการกับจุดลอยตัวที่ไม่แม่นยำ ฉันไม่คิดว่าฉันเคยเห็นพฤติกรรมนี้ในภาษาอื่นซึ่งฉันคิดว่าพวกเขามีวิธีแก้ปัญหาในตัว
Mark Adamson

ฉันคิดว่าพวกเขาตั้งใจที่จะรักษาคุณค่าที่มีอยู่อย่าง จำกัด ในระดับความแม่นยำ พวกเขากำลังหาว่าค่าที่เป็น 5.555 นั้นน่าจะเป็นผลมาจากค่า "ของจริง" ที่ 5.5546 เป็น 5.5554 อย่างไรก็ตามหากคุณเล่นเกมการปัดเศษต่อไป 5.444445 อาจจบลงด้วยการไม่ได้รับการทดสอบว่า "6" หากคุณทำทีละหนึ่งหลัก แต่คุณอาจพูดถูกว่ามันอาจจะเป็นเรื่องของการเป็นตัวแทนไบนารีเป็นบิตภายใต้หรือมากกว่า 5.55
mpag

ใช่ฉันคิดว่าถ้ามันเป็นความตั้งใจมันจะสอดคล้องกันระหว่าง 5.565 และ 5.545 'การสุ่ม' แนะนำให้ฉันมันเป็นสิ่งที่แสดงถึงจุดลอยตัว
Mark Adamson

พวกคุณคนใดสามารถช่วยได้ในเรื่องนี้? stackoverflow.com/q/53279593/5224236
gpier

8

อะไรแบบนั้น :

options(digits=2)

ตัวเลือกนิยามของหลัก:

digits: controls the number of digits to print when printing numeric values.

มีวิธีการตั้งค่าแบบไดนามิกนี้เมื่อใช้สคริปต์หรือไม่
Brandon Bertelsen

ใช้งานได้กับการแสดงผลภายในคอนโซล R แต่ไม่ทำงานในสคริปต์ของฉัน (พวกเขายังออกมาพร้อมกับ. 1289273982)
Brandon Bertelsen

1
ฉันได้รับพฤติกรรมแปลก ๆdigitsดูเหมือนว่าตัวเลือกจะไม่ตั้งจำนวนหลักหลังจุดทศนิยม เช่นเมื่อฉันตั้งค่าตัวเลือก (ตัวเลข = 2) แล้วการพิมพ์ 7.25 ผลลัพธ์ในผลลัพธ์ของ 7.2, 1234.25 กลายเป็น 1234 และ 0.25 ยังคง 0.25 มีตัวเลือกอื่นโต้ตอบกับสิ่งนี้หรือไม่
Maxim.K

8

ตรวจสอบฟังก์ชั่นสวย ๆ , รูปแบบ

มีค่าศูนย์ trialling (ตัวอย่าง 123.1240) sprintf(x, fmt='%#.4g')


@ 42 ฉันอยากจะสนับสนุนให้เรียนรู้sprintfมันเป็นกรอบสำหรับการจัดรูปแบบ
jangorecki

1
@angorecki ฉันไม่แน่ใจในประเด็นของคุณ ทั้งหมดที่ฉันทำ (5+ ปีก่อน) ถูกแนะนำให้แก้ไขการสะกดคำ
IRTFM

@ 42 ฉันจะบ่นเกี่ยวกับfmtหาเรื่องขอโทษ!
jangorecki

ฉันคิดว่า OP เป็นตำแหน่งทศนิยมหลังคงที่แทนที่จะเป็นตัวเลขคงที่ ดูเหมือนว่าgในคำตอบของคุณสำหรับตัวเลขคงที่โดยใช้fงานได้ดีขึ้น
Mark Adamson

5

หากคุณต้องการให้ตัวเลขที่มีนัยสำคัญกับตัวเลขคงที่คำสั่งsignifอาจมีประโยชน์:

> signif(1.12345, digits = 3)
[1] 1.12
> signif(12.12345, digits = 3)
[1] 12.1
> signif(12345.12345, digits = 3)
[1] 12300

1
ขอบคุณพอล สองคนนี้ไม่ใช่สิ่งที่ฉันกำลังมองหา แต่ signif ทำให้ฉันต้องปัดเศษ () ซึ่งเป็นสิ่งที่ฉันต้องการ ไชโย
แบรนดอน Bertelsen

34
Error: could not find function "fixed"
ThomasH

signifทำงานได้กับจำนวนเฉพาะที่ให้ไว้ แต่ฉันเข้าใจว่าปัญหาที่นำไปใช้ทั่วไปคือเมื่อคุณต้องการแสดงทศนิยมสองตำแหน่ง แต่คุณไม่ทราบว่าหมายเลขนั้นเป็นเวลาใด ในกรณีนั้นsignifจะให้ตัวเลขทศนิยมที่แตกต่างกันขึ้นอยู่กับจำนวนจริง
Jeromy Anglim

3
คงที่ไม่พบที่ใดก็ได้ โปรดแก้ไขมิฉะนั้นคำตอบที่ทำให้เข้าใจผิดนี้ควรถูกลบ
HelloWorld

@JeromyAnglim เราจะแก้ไขได้อย่างไรเมื่อเราต้องการ 3sf? บางครั้งมันให้ 3sf กับอีกครั้ง 4sf ฯลฯ เราจะแก้ไขได้อย่างไร
christouandr7

4

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


3

ฉันใช้ตัวแปรนี้เพื่อบังคับให้พิมพ์ทศนิยมทศนิยม K:

# format numeric value to K decimal places
formatDecimal <- function(x, k) format(round(x, k), trim=T, nsmall=k)

2

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


3
ยืนยันว่าเป็นเพียงตัวอย่างเท่านั้น ฉันบดแป้นพิมพ์
Brandon Bertelsen

1

ดูเหมือนว่าฉันจะเป็นอย่างนั้น

library(tutoR)
format(1.128347132904321674821, 2)

ต่อเล็ก ๆ น้อย ๆความช่วยเหลือออนไลน์


ฉันพบสิ่งนี้ แต่ต้องใช้แพ็คเกจฉันกำลังมองหาบางอย่างภายในแพ็คเกจพื้นฐาน
Brandon Bertelsen

2
@brandon, format () เป็นส่วนหนึ่งของฐาน เปิด R และพิมพ์? ฟอร์แมต ... ไม่จำเป็นต้องใช้แพ็คเกจ
JD Long

Hrmmm คุณดูสิ่งที่ผลลัพธ์นี้หรือไม่ [1] "1.128347" ไม่อย่างนั้นคุณค่อนข้างถูกต้องว่ามันอยู่ในแพ็คเกจพื้นฐานใช่ไหม
Brandon Bertelsen

1
อาจลอง format.default(x, digits = 2)ถ่ายภาพในที่มืดโดยอ้างอิงจากลิงก์ที่ให้ไว้ ข้อมูลนั้นเป็นสิ่งที่ขาดไปจากสิ่งที่ฉันปกติอ่านสำหรับเอกสารฉันคาดว่าจะเห็นผลลัพธ์ที่พิมพ์ออกมาเช่นกัน
Tim Meers

เพิ่งสังเกตเห็นว่าลิงก์ของคุณชี้ไปที่เอกสาร tutoR ซึ่งไม่ได้เป็นส่วนหนึ่งของฐาน
Brandon Bertelsen

1

หากคุณต้องการปัดเศษตัวเลขหรือรายการให้ใช้

round(data, 2)

จากนั้นข้อมูลจะถูกปัดเศษเป็นทศนิยม 2 ตำแหน่ง

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