477 Stimmen

Wie fügt man führende Nullen hinzu?

Ich habe einen Datensatz, der in etwa wie folgt aussieht:

anim <- c(25499,25500,25501,25502,25503,25504)
sex  <- c(1,2,2,1,2,1)
wt   <- c(0.8,1.2,1.0,2.0,1.8,1.4)
data <- data.frame(anim,sex,wt)

data
   anim sex  wt anim2
1 25499   1 0.8     2
2 25500   2 1.2     2
3 25501   2 1.0     2
4 25502   1 2.0     2
5 25503   2 1.8     2
6 25504   1 1.4     2

Ich möchte, dass vor jeder Tier-ID eine Null hinzugefügt wird:

data
   anim sex  wt anim2
1 025499   1 0.8     2
2 025500   2 1.2     2
3 025501   2 1.0     2
4 025502   1 2.0     2
5 025503   2 1.8     2
6 025504   1 1.4     2

Und was ist, wenn ich interessehalber zwei oder drei Nullen vor den Tier-IDs hinzufügen muss?

9 Stimmen

Angenommen, Sie möchten n Nullen vor den Tier-IDs hinzufügen, dann müssen Sie nur Folgendes tun data$anim = paste(rep(0, n), data$anim, sep = "")

3 Stimmen

Wenn Sie sagen, dass Sie "Nullen hinzufügen" möchten, möchten Sie vermutlich nicht Ihre Integer-Spalten in String/Kategorisch konvertieren, um die Nullen in den Daten selbst hinzuzufügen, sondern Sie möchten sie ganzzahlig lassen und beim Rendern der Ausgabe nur führende Nullen ausgeben .

756voto

Richie Cotton Punkte 112708

Die Kurzversion: Verwenden Sie formatC o sprintf .


Die längere Version:

Für die Formatierung von Zahlen stehen mehrere Funktionen zur Verfügung, darunter das Hinzufügen führender Nullen. Welche Funktion am besten geeignet ist, hängt davon ab, welche anderen Formatierungen Sie vornehmen möchten.

Das Beispiel aus der Frage ist recht einfach, da alle Werte zunächst die gleiche Anzahl von Ziffern haben. Versuchen wir es also mit einem schwierigeren Beispiel, bei dem es darum geht, Potenzen von 10 mit 8 zu bilden.

anim <- 25499:25504
x <- 10 ^ (0:5)

paste (und seine Variante paste0 ) sind oft die ersten Funktionen zur Manipulation von Zeichenketten, die Sie kennenlernen. Sie sind eigentlich nicht für die Manipulation von Zahlen gedacht, aber sie können dafür verwendet werden. In dem einfachen Fall, dass wir immer eine einzelne Null voranstellen müssen, paste0 ist die beste Lösung.

paste0("0", anim)
## [1] "025499" "025500" "025501" "025502" "025503" "025504"

Für den Fall, dass die Zahlen eine variable Anzahl von Ziffern enthalten, müssen Sie manuell berechnen, wie viele Nullen voranzustellen sind, was so schrecklich ist, dass Sie es nur aus krankhafter Neugier tun sollten.


str_pad de stringr funktioniert ähnlich wie paste Dadurch wird deutlicher, dass Sie die Dinge auffüllen wollen.

library(stringr)
str_pad(anim, 6, pad = "0")
## [1] "025499" "025500" "025501" "025502" "025503" "025504"

Auch hier ist es nicht wirklich für die Verwendung mit Zahlen ausgelegt, so dass der härtere Fall ein wenig Überlegung erfordert. Wir sollten in der Lage sein, einfach zu sagen: "Pad mit Nullen auf Breite 8", aber sehen Sie sich diese Ausgabe an:

str_pad(x, 8, pad = "0")
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "0001e+05"

Sie müssen die wissenschaftliche Strafe festlegen Option damit die Zahlen immer in fester Notation (und nicht in wissenschaftlicher Notation) formatiert werden.

library(withr)
with_options(
  c(scipen = 999), 
  str_pad(x, 8, pad = "0")
)
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"

stri_pad en stringi funktioniert genau wie str_pad de stringr .


formatC ist eine Schnittstelle zu der C-Funktion printf . Die Verwendung dieser Funktion erfordert einige Kenntnisse über die zugrunde liegende Funktion (siehe Link). In diesem Fall sind die wichtigsten Punkte die width Argument, format unter "d" für "Ganzzahl" und ein "0" flag um Nullen voranzustellen.

formatC(anim, width = 6, format = "d", flag = "0")
## [1] "025499" "025500" "025501" "025502" "025503" "025504"
formatC(x, width = 8, format = "d", flag = "0")
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"

Dies ist meine bevorzugte Lösung, da es einfach ist, die Breite zu ändern, und die Funktion leistungsfähig genug ist, um andere Formatierungsänderungen vorzunehmen.


sprintf ist eine Schnittstelle zu der gleichnamigen C-Funktion; wie formatC aber mit einer anderen Syntax.

sprintf("%06d", anim)
## [1] "025499" "025500" "025501" "025502" "025503" "025504"
sprintf("%08d", x)
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"

Der Hauptvorteil von sprintf ist, dass Sie formatierte Zahlen in längere Textabschnitte einbetten können.

sprintf(
  "Animal ID %06d was a %s.", 
  anim, 
  sample(c("lion", "tiger"), length(anim), replace = TRUE)
)
## [1] "Animal ID 025499 was a tiger." "Animal ID 025500 was a tiger."
## [3] "Animal ID 025501 was a lion."  "Animal ID 025502 was a tiger."
## [5] "Animal ID 025503 was a tiger." "Animal ID 025504 was a lion." 

Siehe auch Antwort von goodside .


Der Vollständigkeit halber sollten auch die anderen Formatierungsfunktionen erwähnt werden, die gelegentlich nützlich sind, aber keine Methode zum Voranstellen von Nullen haben.

format , eine allgemeine Funktion zur Formatierung beliebiger Objekte, mit einer Methode für Zahlen. Sie funktioniert ein wenig wie formatC , aber mit einer anderen Schnittstelle.

prettyNum ist eine weitere Formatierungsfunktion, die hauptsächlich zur Erstellung manueller Achsenbeschriftungen dient. Sie eignet sich besonders gut für große Zahlenbereiche.

En scales Paket hat mehrere Funktionen wie percent , date_format y dollar für spezielle Formattypen.

256voto

goodside Punkte 4091

Für eine allgemeine Lösung, die unabhängig von der Anzahl der Ziffern in data$anim verwenden Sie die sprintf Funktion. Sie funktioniert folgendermaßen:

sprintf("%04d", 1)
# [1] "0001"
sprintf("%04d", 104)
# [1] "0104"
sprintf("%010d", 104)
# [1] "0000000104"

In Ihrem Fall wollen Sie das wahrscheinlich: data$anim <- sprintf("%06d", data$anim)

39voto

metasequoia Punkte 6672

Ich erweitere die Antwort von @goodside:

In manchen Fällen kann es sinnvoll sein, eine Zeichenkette mit Nullen aufzufüllen (z. B. bei Fips-Codes oder anderen numerisch ähnlichen Faktoren). Unter OSX/Linux:

> sprintf("%05s", "104")
[1] "00104"

Aber weil sprintf() ruft das C des Betriebssystems sprintf() Befehl, besprochen aquí In Windows 7 erhalten Sie ein anderes Ergebnis:

> sprintf("%05s", "104")
[1] "  104"

Auf Windows-Rechnern lässt sich das Problem also umgehen:

> sprintf("%05d", as.numeric("104"))
[1] "00104"

33voto

kdauria Punkte 5977

str_pad von der stringr Paket ist eine Alternative.

anim = 25499:25504
str_pad(anim, width=6, pad="0")

2voto

Tyler Rinker Punkte 103407

Hier ist eine verallgemeinerbare Basisfunktion von R:

pad_left <- function(x, len = 1 + max(nchar(x)), char = '0'){

    unlist(lapply(x, function(x) {
        paste0(
            paste(rep(char, len - nchar(x)), collapse = ''),
            x
        )
    }))
}

pad_left(1:100)

Ich mag sprintf aber es gibt auch Vorbehalte wie:

die tatsächliche Implementierung wird jedoch dem C99-Standard folgen, und feine Details (insbesondere das Verhalten bei Benutzerfehlern) können von der Plattform abhängen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X