Formatowanie miejsc dziesiętnych w R.


264

Mam numer, na przykład 1.128347132904321674821, który chciałbym wyświetlać jako tylko dwa miejsca po przecinku podczas wyświetlania na ekranie (lub zapisywaniu do pliku). Jak to zrobić?

x <- 1.128347132904321674821

EDYTOWAĆ:

Sposób użycia:

options(digits=2)

Zostało zasugerowane jako możliwa odpowiedź. Czy istnieje sposób na określenie tego w skrypcie do jednorazowego użytku? Gdy dodam go do skryptu, wydaje się, że nie robi nic innego i nie jestem zainteresowany ponownym pisaniem w celu sformatowania każdej liczby (automatyzuję bardzo duży raport).

-

Odpowiedź: okrągły (x, cyfry = 2)



Jeśli używa się opcji (cyfry = 4), to nie ogranicza obliczeń do 4 cyfr, prawda? W takim przypadku programy byłyby znacznie mniej dokładne. Wpływa TYLKO na liczbę, kiedy jest drukowana, prawda?
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.z opcji? wpływa tylko na wynik.
Brandon Bertelsen,

Pamiętaj, że round(23, digits=2)wydrukuje, 23a nie 23.00. Jeśli chcesz tego drugiego, spróbuj stackoverflow.com/a/12135122/180892
Jeromy Anglim

4
@PaulHurleyuk, myślę, że dobrą praktyką w programowaniu jest używanie jak najmniejszej liczby bibliotek. Ktoś, kto używa innej biblioteki dla każdego trywialne potrzeby zazwyczaj kończy się bałagan, dużych plików, kwestie przenośności, itp
Rodrigo

Odpowiedzi:


381

Tło: Niektóre odpowiedzi je na tej stronie (np signif, options(digits=...)) nie gwarantują, że pewna liczba miejsc po przecinku są wyświetlane dla dowolnej liczby. Zakładam, że jest to cecha projektowa w R, zgodnie z którą dobra praktyka naukowa polega na pokazywaniu pewnej liczby cyfr w oparciu o zasady „ znaczących cyfr ”. Jednak w wielu domenach (np. Styl APA , raporty biznesowe) wymagania dotyczące formatowania nakazują wyświetlanie pewnej liczby miejsc dziesiętnych. Odbywa się to często w celach spójności i standaryzacji, a nie w przypadku znaczących liczb.

Rozwiązanie :

Poniższy kod pokazuje dokładnie dwa miejsca po przecinku dla liczby x.

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

Na przykład:

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"

Bardziej ogólna funkcja jest następująca, gdzie xjest liczba i kliczba miejsc po przecinku do wyświetlenia. trimwsusuwa wszelkie białe znaki, które mogą być przydatne, jeśli masz wektor liczb.

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

Na przykład,

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

4
+1 Tylko odpowiedź, która zadziałała dla mnie, poprawnie drukowana 0.0001jako0.00
ThomasH

7
Zawsze martwiło mnie, jak funkcje lubią cyfry format()i prettyNum()przekształcają się w znaki. Jak byś to rozwiązał?
Waldir Leoncio

Co z cytatami, które się pojawiają?
F.Webber

2
@JeromyAnglim Zwracam uwagę, że powyższe rozwiązanie może mieć niedogodność na krawędziach, polegającą na ustalaniu liczby znaków przed przecinkiem, np. format(c(10, 1), nsmall=1)Plonów "10.0" " 1.0"(zwróć uwagę na wiodącą spację przed 1.0. Podczas gdy sprintf()funkcja wydaje się gwarantować ładniejsze formatowanie na obie strony po przecinku, np sprintf(c(10,1), fmt = '%#.1f')pozbywa się tego nieznośnego wiodącej przestrzeni i zwrotów "10.0" "1.0".
Nicholas G Reich

1
Przednie spacje to funkcja zaprojektowana w celu wyrównania punktu dziesiętnego, gdy wynik formatjest użyty w kolumnie.
Mieszkaniec

34

Możesz sformatować liczbę, powiedzmy x, do miejsc po przecinku, jak chcesz. Oto xliczba z wieloma miejscami dziesiętnymi. Załóżmy, że chcemy pokazać do 8 miejsc po przecinku tej liczby:

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

Tutaj format="f"daje liczb zmiennoprzecinkowych w zwykłych miejsc po przecinku powiedzieć, xxx.xxx i digitsokreśla liczbę cyfr. Natomiast jeśli chcesz uzyskać liczbę całkowitą do wyświetlenia, użyłbyś format="d"(podobnie jak sprintf).


Chociaż nie jestem pewien, o co dokładnie prosi OP, sądząc po najwyższej ocenie odpowiedzi, nie mogłem nie zauważyć, że formatCprawie tego używam do tego celu. Myślę, że ta odpowiedź jest dobra i znajduje się w bazie R na żądanie PO.
AdamO

ktoś z was mógłby pomóc w tym? stackoverflow.com/q/53279593/5224236
gpier

24

Możesz wypróbować mój pakiet formable .

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

Dobrą rzeczą jest to, że xnadal jest wektorem numerycznym i można wykonać więcej obliczeń przy tym samym formatowaniu.

> x + 1
[1] 2.13

Co więcej, cyfry nie są zgubione, w dowolnym momencie możesz sformatować więcej cyfr :)

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

Taki mały kutas wkurza mnie cały ranek. Z jakiegoś powodu R zaokrągli w górę wyświetlacz tylko dla niektórych kolumn. Potrzebowałem tej poprawki, ponieważ musiałem również wykonać obliczenia na tych kolumnach. To działa. Dzięki !
thethakuri

Lubię formableable niż jakiekolwiek funkcje baseR. Największą zaletą jest to, że zachowuje zmienną jako numeryczną.
Lazarus Thurston

22

dla 2 miejsc po przecinku, zakładając, że chcesz zachować końcowe zera

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

co daje

[1] "5.50"

Jak wspomniano poniżej @mpag, wydaje się, że R może czasem dać nieoczekiwane wartości za pomocą tej i okrągłej metody, np. Sprintf (5.5550, fmt = '% #. 2f') daje 5,55, a nie 5,56


1
jednak, choć sprintf zaokrągla, sprintf (5.5550, fmt = '% #. 2f') daje nieco nieoczekiwany wynik: 5,55. sprintf (5.555000000001, fmt = '% #. 2f') daje 5,56. Wydaje się, że jest to ogólny „problem” z zaokrąglaniem w R, ponieważ metoda round, nsmall daje to samo.
MPag

Dzięki @mpag, nie miałem pojęcia, że ​​R miał problem z zaokrąglaniem granic, właśnie wypróbowałem go z 5.565, który zaokrągla w górę, a 5.545 zaokrągla w dół. Myślę, że to sposób, w jaki radzą sobie z precyzją zmiennoprzecinkową. Nie sądzę, że widziałem takie zachowanie w innych językach, co, jak sądzę, oznacza, że ​​mają one wbudowane obejście
Mark Adamson

Myślę raczej, że celowo traktują wartości jako ograniczone pod względem precyzji. Zakładają, że wartość 5.555 jest tak samo prawdopodobne, że wynikałaby z „rzeczywistej” wartości 5.5546 jako 5.5554. Jeśli jednak będziesz kontynuować grę zaokrąglającą, 5.444445 może (nieprzetestowane) skończyć jako „6”, jeśli zrobisz to po jednej cyfrze. Ale możesz mieć rację, że reprezentacja binarna może być nieco poniżej lub powyżej 5,55.
MPag

Tak, myślę, że gdyby był celowy, byłby również zgodny między 5.565 a 5.545. „Losowość” sugeruje mi, że jest to reprezentacja zmiennoprzecinkowa.
Mark Adamson,

ktoś z was mógłby pomóc w tym? stackoverflow.com/q/53279593/5224236
gpier

8

Coś w tym stylu :

options(digits=2)

Definicja opcji cyfr:

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

Czy jest jakiś sposób, aby ustawić to dynamicznie podczas uruchamiania skryptu?
Brandon Bertelsen,

Działa to w przypadku wyświetlania w konsoli R, ale nie działa w moim skrypcie (wciąż pojawiają się z .1289273982)
Brandon Bertelsen

1
Mam dziwne zachowanie, digitsopcja nie wydaje się ustawiać liczby cyfr po przecinku. Na przykład, gdy ustawię opcje (cyfry = 2), wówczas wydruk 7,25 daje wynik w postaci 7.2, 1234.25 staje się 1234, a 0.25 pozostaje 0.25. Czy istnieje inna opcja interakcji z tym?
Maxim.K

8

Sprawdź funkcje prettyNum, format

mieć próbne zera (na przykład 123.1240) sprintf(x, fmt='%#.4g')


@ 42 sprintf
Radziłbym

1
@jangorecki Nie jestem pewien twojego punktu widzenia. Wszystko, co zrobiłem (ponad 5 lat temu), sugerowało korektę pisowni.
IRTFM

@ 42 Trudno, skarżysz się na fmtarg.
jangorecki

Myślę, że OP ma ustalone miejsca dziesiętne, a nie stałe cyfry. Wygląda na to, że gTwoja odpowiedź dotyczy cyfr stałych, a korzystanie z nich fdziała lepiej.
Mark Adamson,

5

Jeśli wolisz cyfry znaczące niż stałe, wówczas przydatne może być polecenie 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
Dzięki Paul. Te dwa nie były dokładnie tym, czego szukałem, ale signif doprowadził mnie do round (), czego dokładnie potrzebowałem. Pozdrawiam,
Brandon Bertelsen,

34
Error: could not find function "fixed"
ThomasH

signifdziała dla podanej liczby, ale przypuszczam, że najczęściej stosowanym problemem jest to, że musisz pokazać dokładnie dwa miejsca po przecinku, ale nie wiesz, jaka liczba jest z góry. W takim przypadku signifpoda różne liczby miejsc po przecinku w zależności od rzeczywistej liczby.
Jeromy Anglim

3
naprawiono nigdzie nie znaleziono. Napraw to, w przeciwnym razie ta myląca odpowiedź powinna zostać usunięta.
HelloWorld

@JeromyAnglim jak to naprawić, kiedy chcemy 3sf? czasami daje mi 3sf, innym razem 4sf itp. jak to naprawić?
christouandr7

4

Za pomocą tej funkcji formatC()można sformatować liczbę z dokładnością do dwóch miejsc po przecinku. Ta funkcja podaje dwa miejsca po przecinku, nawet jeśli wynikowe wartości zawierają końcowe zera.


3

Używam tego wariantu do wymuszonego drukowania miejsc dziesiętnych K:

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

2

Zauważ, że obiekty numeryczne w R są przechowywane z podwójną precyzją , co daje (z grubsza) 16 cyfr dziesiętnych precyzji - reszta będzie szumem. Przyznaję, że powyższy numer jest prawdopodobnie tylko przykładem, ale ma 22 cyfry.


3
Potwierdzony, to tylko przykład. Przetarłem klawiaturę.
Brandon Bertelsen,

1

Wygląda mi na to, że byłoby coś takiego

library(tutoR)
format(1.128347132904321674821, 2)

Za małą pomoc online .


Znalazłem to, ale wymaga pakietu, szukam czegoś w pakiecie podstawowym.
Brandon Bertelsen

2
@brandon, format () jest częścią bazy. Otwórz format R i wpisz? ... żadne pakiety nie są potrzebne.
JD Long

Hmmmm, spojrzałeś na to, co to daje? [1] „1.128347” w przeciwnym razie, masz rację, że jest w pakiecie podstawowym, niestety.
Brandon Bertelsen,

1
Być może spróbuj format.default(x, digits = 2)po prostu strzału w ciemność, na podstawie podanego linku. Ta informacja jest tym, czego brakuje w tym, co normalnie czytam do dokumentacji, spodziewałem się również zobaczyć wydruków.
Tim Meers,

Właśnie zauważyłem, że twój link wskazuje na dokumentację tutoR, która nie jest częścią bazy.
Brandon Bertelsen,

1

jeśli chcesz tylko zaokrąglić liczbę lub listę, po prostu użyj

round(data, 2)

Następnie dane będą zaokrąglane do 2 miejsc po przecinku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.