Memformat tempat desimal di R

264

Saya memiliki nomor, misalnya 1.128347132904321674821 yang ingin saya tunjukkan sebagai hanya dua tempat desimal ketika output ke layar (atau ditulis ke file). Bagaimana seseorang melakukan itu?

x <- 1.128347132904321674821

EDIT:

Penggunaan:

options(digits=2)

Telah disarankan sebagai jawaban yang memungkinkan. Apakah ada cara untuk menentukan ini dalam skrip untuk penggunaan satu kali? Ketika saya menambahkannya ke skrip saya sepertinya tidak melakukan hal yang berbeda dan saya tidak tertarik dalam banyak mengetik ulang untuk memformat setiap angka (saya mengotomatisasi laporan yang sangat besar).

-

Jawab: bulat (x, digit = 2)

Brandon Bertelsen
sumber
1
Pertanyaan terkait: stackoverflow.com/questions/2287616/…
Shane
Jika seseorang menggunakan opsi (digit = 4), itu tidak membatasi perhitungan hingga 4 digit, bukan? Dalam hal ini akan membuat program jauh kurang akurat. HANYA memengaruhi nomor ketika dicetak, benar?
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.dari? opsi itu hanya efek keluaran.
Brandon Bertelsen
Catatan yang round(23, digits=2)akan dicetak 23dan tidak 23.00. Jika Anda menginginkan yang terakhir, coba stackoverflow.com/a/12135122/180892
Jeromy Anglim
4
@ PaulHurleyuk, saya pikir ini praktik yang baik dalam pemrograman untuk menggunakan perpustakaan seminimal mungkin. Seseorang yang menggunakan perpustakaan berbeda untuk setiap kebutuhan sepele biasanya berakhir dengan kekacauan, file besar, masalah portabilitas, dll.
Rodrigo

Jawaban:

381

Latar Belakang: Beberapa jawaban yang disarankan pada halaman ini (mis. signif, options(digits=...)) Tidak menjamin bahwa sejumlah desimal ditampilkan untuk angka acak. Saya kira ini adalah fitur desain dalam R di mana praktik ilmiah yang baik melibatkan menunjukkan sejumlah digit berdasarkan pada prinsip " angka penting ". Namun, di banyak domain (misalnya, gaya APA , laporan bisnis) persyaratan pemformatan menentukan bahwa sejumlah tempat desimal ditampilkan. Ini sering dilakukan untuk tujuan konsistensi dan standardisasi daripada mementingkan angka-angka penting.

Solusi :

Kode berikut menunjukkan tepat dua tempat desimal untuk angka tersebut x.

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

Sebagai contoh:

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"

Fungsi yang lebih umum adalah sebagai berikut di mana xnomor dan kjumlah desimal untuk ditampilkan. trimwsmenghilangkan spasi putih terdepan yang dapat berguna jika Anda memiliki vektor angka.

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

Misalnya,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"
Jeromy Anglim
sumber
4
+1 Hanya jawaban yang berfungsi untuk saya, dicetak dengan benar 0.0001sebagai0.00
ThomasH
7
Itu selalu mengganggu saya bagaimana fungsi suka format()dan prettyNum()mengubah angka menjadi karakter. Bagaimana Anda mengatasinya?
Waldir Leoncio
Ada apa dengan kutipan yang muncul?
F.Webber
2
@JeromyAnglim Saya perhatikan bahwa solusi di atas memiliki kemungkinan tepi-kasus yang merugikan dari memperbaiki jumlah karakter di depan desimal, misalnya format(c(10, 1), nsmall=1)hasil "10.0" " 1.0"(perhatikan ruang terdepan di depan angka 1.0. Padahal, sprintf()fungsi tersebut tampaknya menjamin pemformatan yang lebih baik pada kedua sisi desimal, misalnya sprintf(c(10,1), fmt = '%#.1f')menghilangkan yang sial ruang terkemuka dan pengembalian "10.0" "1.0".
Nicholas G Reich
1
Spasi utama adalah fitur yang dirancang untuk menyelaraskan titik desimal saat hasil formatdigunakan dalam kolom.
Penduduk
34

Anda dapat memformat angka, katakanlah x, hingga tempat desimal sesuai keinginan. Ini xadalah angka dengan banyak tempat desimal. Misalkan kita ingin menampilkan hingga 8 angka desimal dari angka ini:

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

Di sini format="f"memberikan angka mengambang di tempat desimal yang biasa katakan, xxx.xxx, dan digitsmenentukan jumlah digit. Sebaliknya, jika Anda ingin mendapatkan bilangan bulat untuk ditampilkan, Anda akan menggunakan format="d"(seperti sprintf).

SORIF HOSSAIN
sumber
Walaupun saya tidak tahu persis apa yang diminta OP, menilai dengan jawaban berperingkat tertinggi, saya tidak bisa tidak mengamati bahwa formatChampir secara eksklusif apa yang saya gunakan untuk tujuan ini. Saya pikir jawaban ini baik dan berada di basis R sesuai permintaan OP.
AdamO
Adakah di antara kalian yang bisa membantu yang ini? stackoverflow.com/q/53279593/5224236
gpier
24

Anda dapat mencoba paket saya bisa diformat .

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

Yang menyenangkan adalah, xmasih berupa vektor numerik dan Anda dapat melakukan lebih banyak perhitungan dengan format yang sama.

> x + 1
[1] 2.13

Bahkan lebih baik, digit tidak hilang, Anda dapat memformat ulang dengan lebih banyak digit kapan saja :)

> formattable(x, digits = 6, format = "f")
[1] 1.128347
Kun Ren
sumber
Bajingan kecil yang menggangguku sepanjang pagi. Untuk beberapa alasan R akan mengumpulkan tampilan hanya untuk beberapa kolom. Saya perlu perbaikan ini karena saya harus melakukan perhitungan pada kolom-kolom itu juga. Ini bekerja. Terima kasih!
thethakuri
Saya suka diformat daripada fungsi baseR. Keuntungan terbesarnya mempertahankan variabel sebagai numerik.
Lazarus Thurston
22

untuk 2 tempat desimal dengan asumsi bahwa Anda ingin tetap membuntuti nol

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

pemberian yang mana

[1] "5.50"

Seperti @mpag menyebutkan di bawah ini, tampaknya R kadang-kadang dapat memberikan nilai yang tidak terduga dengan ini dan metode bulat misalnya sprintf (5.5550, fmt = '% #. 2f') memberikan 5.55, bukan 5.56

Mark Adamson
sumber
1
namun, meskipun putaran sprintf, sprintf (5.5550, fmt = '% #. 2f') memberikan hasil yang sedikit tidak terduga: 5.55. sprintf (5.555000000001, fmt = '% #. 2f') memberikan 5.56. Ini tampaknya menjadi "masalah" umum dengan pembulatan dalam R, karena metode bulat, nsmall memberikan hal yang sama.
mpag
Terima kasih @mpag, saya tidak tahu bahwa R berjuang dengan pembulatan pada batas-batas, saya baru saja mencobanya dengan 5.565 yang tidak bulat, sementara 5,545 putaran ke bawah. Saya kira itu adalah cara mereka menangani keputusan floating point. Saya tidak berpikir saya telah melihat perilaku ini dalam bahasa lain yang saya kira berarti mereka memiliki solusi bawaan
Mark Adamson
Saya pikir mereka sengaja memperlakukan nilai-nilai sebagai terbatas dalam tingkat presisi. Mereka memperkirakan bahwa nilai yang 5.555 benar-benar sama mungkin telah dihasilkan dari nilai "nyata" dari 5.5546 sebagai 5.5554. Namun, jika Anda melanjutkan permainan pembulatan semacam itu, 5.444445 mungkin (belum diuji) berakhir sebagai "6" jika Anda melakukannya satu digit pada satu waktu. Tetapi Anda mungkin benar bahwa itu mungkin masalah representasi biner yang sedikit di bawah atau di atas 5,55.
mpag
Ya, saya pikir jika disengaja itu juga akan konsisten antara 5,565 dan 5,545. 'Keacakan' menunjukkan kepada saya itu adalah hal representasi titik mengambang.
Mark Adamson
Adakah di antara kalian yang bisa membantu yang ini? stackoverflow.com/q/53279593/5224236
gpier
8

Sesuatu seperti itu :

options(digits=2)

Opsi definisi digit:

digits: controls the number of digits to print when printing numeric values.
Xavier V.
sumber
Apakah ada cara untuk mengatur ini secara dinamis saat menjalankan skrip?
Brandon Bertelsen
Ini berfungsi untuk menghasilkan dalam konsol R, tetapi tidak berfungsi dalam skrip saya (mereka masih keluar dengan .1289273982)
Brandon Bertelsen
1
Saya mendapatkan perilaku aneh, digitsopsi tampaknya tidak menetapkan jumlah digit setelah desimal. Misalnya, ketika saya mengatur opsi (digit = 2), kemudian mencetak 7,25 menghasilkan output 7,2, 1234,25 menjadi 1234, dan 0,25 tetap 0,25. Apakah ada opsi lain untuk berinteraksi dengan ini?
Maxim.K
8

Periksa fungsi prettyNum, format

untuk memiliki nol percobaan (123.1240 misalnya) gunakan sprintf(x, fmt='%#.4g')

ilya
sumber
@ 42 Saya akan menganjurkan untuk belajar sprintf, ini pada dasarnya adalah kerangka kerja untuk memformat
jangorecki
1
@ Jongorecki Saya tidak yakin dengan maksud Anda. Yang saya lakukan (5+ tahun yang lalu) adalah menyarankan koreksi ejaan.
IRTFM
@ 42 Saya ingin Anda mengeluh tentang fmtarg, maaf!
jangorecki
Saya pikir OP adalah setelah tempat desimal tetap daripada digit tetap. Tampaknya gjawaban Anda adalah untuk digit tetap, menggunakan fkarya lebih baik.
Mark Adamson
5

Jika Anda lebih suka digit signifikan daripada digit tetap, maka perintah signif mungkin berguna:

> signif(1.12345, digits = 3)
[1] 1.12
> signif(12.12345, digits = 3)
[1] 12.1
> signif(12345.12345, digits = 3)
[1] 12300
PaulHurleyuk
sumber
1
Terima kasih Paul. Keduanya tidak persis apa yang saya cari, tetapi menuntun saya ke round () yang tepat yang saya butuhkan. Cheers,
Brandon Bertelsen
34
Error: could not find function "fixed"
ThomasH
signifberfungsi untuk angka tertentu yang disediakan, tetapi saya menganggap masalah yang umum diterapkan adalah ketika Anda harus menunjukkan dua tempat desimal dengan tepat, tetapi Anda tidak tahu nomor apa yang ada di depan. Dalam hal ini, signifakan memberikan jumlah desimal yang berbeda tergantung pada jumlah sebenarnya.
Jeromy Anglim
3
diperbaiki tidak ditemukan di mana pun. Harap perbaiki, jika tidak jawaban yang menyesatkan ini harus dihapus.
HelloWorld
@ JeromyAnglim bagaimana cara memperbaikinya saat kita menginginkan 3sf? kadang-kadang memberi saya 3sf, lain kali 4sf, dll. bagaimana kita memperbaikinya?
christouandr7
4

Fungsi formatC()ini dapat digunakan untuk memformat angka menjadi dua tempat desimal. Dua tempat desimal diberikan oleh fungsi ini bahkan ketika nilai-nilai yang dihasilkan termasuk nol tambahan.

Chernoff
sumber
3

Saya menggunakan varian ini untuk mencetak desimal K:

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

Perhatikan bahwa objek numerik dalam R disimpan dengan presisi ganda , yang memberi Anda (kira-kira) 16 digit desimal presisi - sisanya akan noise. Saya akui bahwa angka yang ditunjukkan di atas mungkin hanya untuk contoh, tetapi panjangnya 22 digit.

nullglob
sumber
3
Dikonfirmasi, itu hanya untuk contoh. Saya tumbuk keyboard.
Brandon Bertelsen
1

Sepertinya saya ingin menjadi seperti itu

library(tutoR)
format(1.128347132904321674821, 2)

Per sedikit bantuan online .

Tim Meers
sumber
Saya menemukan ini, tetapi membutuhkan paket, saya mencari sesuatu di dalam paket dasar.
Brandon Bertelsen
2
@brandon, format () adalah bagian dari basis. Buka R dan ketik? Format ... tidak perlu paket.
JD Long
Hrmmm, apakah Anda melihat output apa ini? [1] "1.128347" jika tidak, Anda benar tentang hal itu karena berada dalam paket dasar, salahku.
Brandon Bertelsen
1
Mungkin mencoba format.default(x, digits = 2)hanya satu tembakan dalam gelap meskipun berdasarkan tautan yang disediakan. Info itu adalah beberapa kekurangan dari apa yang biasanya saya baca untuk dokumentasi, saya berharap untuk melihat hasil cetak juga.
Tim Meers
Hanya perhatikan bahwa tautan Anda mengarah ke dokumentasi tutoR, yang bukan bagian dari basis.
Brandon Bertelsen
1

jika Anda hanya ingin membulatkan angka atau daftar, cukup gunakan

round(data, 2)

Kemudian, data akan dibulatkan menjadi 2 desimal.

Jared
sumber