Kiểm soát số lượng chữ số thập phân trong đầu ra in trong R


110

Có một tùy chọn trong R để kiểm soát hiển thị chữ số. Ví dụ:

options(digits=10)

được cho là đưa ra kết quả tính toán bằng 10 chữ số cho đến cuối phiên R. Trong tệp trợ giúp của R, định nghĩa cho tham số chữ số như sau:

chữ số: kiểm soát số chữ số cần in khi in giá trị số. Nó chỉ là một gợi ý. Các giá trị hợp lệ là 1 ... 22 với mặc định là 7

Vì vậy, nó nói rằng đây chỉ là một gợi ý. Điều gì sẽ xảy ra nếu tôi muốn luôn hiển thị 10 chữ số, không nhiều hơn hoặc ít hơn?

Câu hỏi thứ hai của tôi là, nếu tôi muốn hiển thị nhiều hơn 22 chữ số, tức là cho các phép tính chính xác hơn như 100 chữ số thì sao? Có thể với cơ sở R không, hay tôi cần một gói / chức năng bổ sung cho điều đó?

Chỉnh sửa: Nhờ gợi ý của jmoy, tôi đã thử sprintf("%.100f",pi)và nó đã cho

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

có 48 số thập phân. Đây có phải là giới hạn tối đa mà R có thể xử lý?


5
Chỉ 15 chữ số đầu tiên của số pi là chính xác. So sánh với giá trị thực joyofpi.com/pi.html
Richie Cotton

1
Bạn đúng. Tại sao nó khác nhau trong R?
Mehper C. Palavuzlar

4
Xem Câu hỏi thường gặp trên R cran.r-project.org/doc/FAQ/…
Richie Cotton

2
Mehper: Tôi nghĩ rằng bạn đang hiểu sai cách biểu diễn tính toán của các số trong R. Bạn có thể muốn đọc en.wikipedia.org/wiki/Floating_point .
Shane

Để so sánh, Python thực hiện chính xác như vậy: Hãy thử python -c "import math; print(format(math.pi, '.100f'))". Kết quả là pivới 48 số thập phân "thực", được nhồi bởi các số 0 cho 52 chữ số còn lại.
cú pháp lỗi

Câu trả lời:


49

Lý do nó chỉ là một gợi ý là bạn có thể khá dễ dàng viết một hàm in mà bỏ qua giá trị tùy chọn. Các chức năng in và định dạng tích hợp sử dụng optionsgiá trị này làm giá trị mặc định.

Đối với câu hỏi thứ hai, vì R sử dụng số học chính xác hữu hạn, câu trả lời của bạn không chính xác vượt quá 15 hoặc 16 chữ số thập phân, vì vậy nói chung, không cần nhiều hơn. Các gói gmprcdd xử lý nhiều số học chính xác (thông qua một số nguyên cho thư viện gmp), nhưng điều này chủ yếu liên quan đến các số nguyên lớn hơn là nhiều chữ số thập phân hơn cho số nhân đôi của bạn.

Mathematica hoặc Maple sẽ cho phép bạn cung cấp bao nhiêu chữ số thập phân mà trái tim bạn mong muốn.

CHỈNH SỬA:
Có thể hữu ích khi nghĩ về sự khác biệt giữa số thập phân và số liệu quan trọng. Nếu bạn đang thực hiện các bài kiểm tra thống kê dựa trên sự khác biệt ngoài con số quan trọng thứ 15, thì phân tích của bạn gần như chắc chắn là rác.

Mặt khác, nếu bạn chỉ xử lý các số rất nhỏ thì điều đó sẽ ít trở ngại hơn, vì R có thể xử lý số nhỏ như .Machine$double.xmin(thường là 2e-308).

So sánh hai phân tích này.

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

Trong trường hợp đầu tiên, sự khác biệt giữa các con số chỉ xảy ra sau nhiều số liệu quan trọng, do đó, dữ liệu là "gần như không đổi". Trong trường hợp thứ hai, Mặc dù kích thước của sự khác biệt giữa các con số là như nhau, nhưng so với độ lớn của bản thân các con số thì chúng rất lớn.


Như e3bo đã đề cập, bạn có thể sử dụng các số dấu phẩy động nhiều độ chính xác bằng cách sử dụng Rmpfrgói.

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Đây là những numericvectơ chậm hơn và tốn nhiều bộ nhớ hơn để sử dụng so với vectơ thông thường (độ chính xác kép) , nhưng có thể hữu ích nếu bạn gặp sự cố có điều kiện kém hoặc thuật toán không ổn định.


4
Như trang Rwiki này trình bày, gói Rmpfr cho phép số học dấu phẩy động có độ chính xác cao trong R.
e3bo

Nhưng Rmpfr có thể được sử dụng bởi bất kỳ gói R nào để cải thiện độ chính xác của nó không? Hay nó chỉ có thể sử dụng các chức năng được mã hóa nội bộ trên đó?
skan

2
Tôi chỉ nghĩ rằng, "Nếu bạn đang thực hiện các bài kiểm tra thống kê dựa trên sự khác biệt ngoài con số có ý nghĩa thứ 15, thì phân tích của bạn gần như chắc chắn là rác." nhưng tôi tự hỏi số chữ số mà tại đó tôi kết luận là rác là bao nhiêu, và tôi nghĩ là 5, nhưng tôi rất vui khi được sửa lại.
PatrickT

46

Nếu bạn đang tự sản xuất toàn bộ đầu ra, bạn có thể sử dụng sprintf(), ví dụ:

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

quy định cụ thể mà bạn muốn định dạng một số dấu chấm động với điểm thập phân mười (trong %.10fnhững flà cho phao và các .10quy định cụ thể các điểm thập phân mười).

Tôi không biết bất kỳ cách nào để buộc các hàm cấp cao hơn của R in ra một số chữ số chính xác.

Việc hiển thị 100 chữ số không có ý nghĩa gì nếu bạn đang in các số thông thường của R, vì độ chính xác tốt nhất mà bạn có thể nhận được khi sử dụng bộ nhân đôi 64 bit là khoảng 16 chữ số thập phân (xem .Machine $ double.eps trên hệ thống của bạn). Các chữ số còn lại sẽ chỉ là rác.


Trên thực tế, một số phép thử chi-square đặc biệt mà tôi đã áp dụng cần hàng trăm số thập phân để đưa ra kết quả chính xác. Ngoài ra số pi có hàng nghìn số thập phân. Đó là lý do tại sao tôi đã tự hỏi về 100 hoặc nhiều chữ số.
Mehper C. Palavuzlar

14
pi có vô số số thập phân; điều đó không có nghĩa là máy tính có thể lưu trữ chúng.
Shane

Tôi đoán đây là một kịch bản mà Mathematica vượt trội hơn R.
skan

1
@skan Bạn có nghĩ rằng Mathematica lưu trữ vô hạn số thập phân không?
Gregor Thomas

@Gregor tất nhiên là không, nhưng bạn có thể có bao nhiêu chữ số mà bộ nhớ của bạn cho phép.
skan

1

Một giải pháp khác có thể kiểm soát số lượng chữ số thập phân cần in ra dựa trên nhu cầu (nếu bạn không muốn in (các) số 0 dư thừa)

Ví dụ: nếu bạn có một vectơ như elementsvà muốn lấy sum

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

Rõ ràng, số cuối cùng 1bị cắt bớt, kết quả lý tưởng sẽ là -876.54321, nhưng nếu được đặt là tùy chọn thập phân in cố định, ví dụ: sprintf("%.10f", sum(elements))(các) số 0 dư thừa sẽ tạo ra-876.5432100000

Làm theo hướng dẫn tại đây: in số thập phân , nếu có thể xác định được có bao nhiêu chữ số thập phân trong một số nào đó, như ở đây -876.54321, có 5 chữ số thập phân cần in thì ta có thể thiết lập tham số cho formathàm như sau:

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

Chúng tôi có thể thay đổi decimal_lengthdựa trên từng truy vấn thời gian, vì vậy nó có thể đáp ứng yêu cầu in thập phân khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.