wake-up-neo.com

Wie füge ich führende Nullen hinzu?

Ich habe einen Datensatz, der ungefähr so ​​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 aus Gründen des Interesses, was ist, wenn ich zwei oder drei Nullen vor den Tier-IDs hinzufügen muss?

309
baz

Die Kurzversion: Verwenden Sie formatC oder sprintf .


Die längere Version:

Zum Formatieren von Zahlen stehen verschiedene Funktionen zur Verfügung, einschließlich des Hinzufügens von führenden Nullen. Welche am besten geeignet ist, hängt davon ab, welche andere Formatierung Sie vornehmen möchten.

Das Beispiel aus der Frage ist recht einfach, da alle Werte von Anfang an die gleiche Anzahl von Ziffern haben. Versuchen wir es also mit einem genaueren Beispiel, bei dem Potenzen von 10 und 8 ebenfalls angegeben werden.

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

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

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

Für den Fall, dass es eine variable Anzahl von Ziffern in den Zahlen gibt, müssen Sie manuell berechnen, wie viele Nullen vorangestellt werden sollen, was schrecklich genug ist, dass Sie dies nur aus krankhafter Neugier tun sollten.


str_pad von stringr funktioniert ähnlich wie paste und macht es expliziter, dass Sie Dinge auffüllen möchten.

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 konzipiert, daher erfordert der schwierigere Fall ein wenig Nachdenken. Wir sollten nur "Pad mit Nullen bis Breite 8" sagen können, aber schauen 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 einstellen Option , damit Zahlen immer in fester Schreibweise (anstatt in wissenschaftlicher Schreibweise) formatiert werden.

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

stri_pad in stringi funktioniert genauso wie str_pad In stringr.


formatC ist eine Schnittstelle zur C-Funktion printf =. Die Verwendung erfordert einige Kenntnisse der Arcana dieser zugrunde liegenden Funktion (siehe Link). In diesem Fall sind die wichtigen Punkte das Argument width, wobei format"d" Für "Ganzzahl" und ein "0"flag für ist Nullen voranstellen.

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 Lieblingslösung, da das Ändern der Breite einfach ist und die Funktion leistungsstark genug ist, um andere Formatierungsänderungen vorzunehmen.


sprintf ist eine Schnittstelle zur 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 besteht darin, dass Sie formatierte Zahlen in längere Textteile 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 goodside's answer .


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

format, eine generische Funktion zum Formatieren beliebiger Objekte mit einer Methode für Zahlen. Es funktioniert ein bisschen wie formatC, aber mit einer weiteren Schnittstelle.

prettyNum ist eine weitere Formatierungsfunktion, hauptsächlich zum Erstellen manueller Achsenmarkierungen. Es funktioniert besonders gut für große Zahlenbereiche.

Das Paket scales hat verschiedene Funktionen wie percent , date_format und dollar für spezielle Formattypen.

488
Richie Cotton

Verwenden Sie für eine allgemeine Lösung, die unabhängig von der Anzahl der Ziffern in data$anim Funktioniert, die Funktion sprintf. Es funktioniert so:

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

In Ihrem Fall möchten Sie wahrscheinlich: data$anim <- sprintf("%06d", data$anim)

200
goodside

Erweiterung der @ goodside-Antwort:

In einigen Fällen möchten Sie möglicherweise eine Zeichenfolge mit Nullen auffüllen (z. B. Fips-Codes oder andere numerische Faktoren). Unter OSX/Linux:

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

Da jedoch sprintf() den Befehl C sprintf() des Betriebssystems aufruft, siehe hier , erhalten Sie in Windows 7 ein anderes Ergebnis:

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

Auf Windows-Computern lautet die Problemumgehung also:

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

str_pad aus dem Paket stringr ist eine Alternative.

anim = 25499:25504
str_pad(anim, width=6, pad="0")
21
kdauria
data$anim <- sapply(0, paste0,data$anim)
2
zhan2383

Hier ist eine verallgemeinerbare Basis-R-Funktion:

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 kommt mit Einschränkungen wie:

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

2
Tyler Rinker

Hier ist eine weitere Alternative zum Hinzufügen von führenden Nullen zu Zeichenfolgen wie CUSIPs , die manchmal wie eine Zahl aussehen können und in vielen Anwendungen wie Excel die führenden Nullen beschädigt und entfernt oder in wissenschaftliche Notation konvertiert werden.

Als ich die Antwort von @metasequoia ausprobierte, hatte der zurückgegebene Vektor führende Leerzeichen und keine 0. Dies war das gleiche Problem, das von @ user1816679 erwähnt wurde - und das Entfernen der Anführungszeichen um 0 Oder das Ändern von %d In %s Machte ebenfalls keinen Unterschied. Zu Ihrer Information, ich verwende RStudio Server, der auf einem Ubuntu-Server ausgeführt wird. Diese kleine zweistufige Lösung hat bei mir funktioniert:

gsub(pattern = " ", replacement = "0", x = sprintf(fmt = "%09s", ids[,CUSIP]))

mit der Pipe-Funktion %>% aus dem Paket magrittr könnte dies so aussehen:

sprintf(fmt = "%09s", ids[,CUSIP]) %>% gsub(pattern = " ", replacement = "0", x = .)

Ich würde eine Ein-Funktions-Lösung vorziehen, aber es funktioniert.

1
Ursus Frost

Für andere Umstände, in denen die Zahlenfolge konsistent sein soll, habe ich eine Funktion erstellt.

Jemand könnte dies nützlich finden:

idnamer<-function(x,y){#Alphabetical designation and number of integers required
    id<-c(1:y)
    for (i in 1:length(id)){
         if(nchar(id[i])<2){
            id[i]<-paste("0",id[i],sep="")
         }
    }
    id<-paste(x,id,sep="")
    return(id)
}
idnamer("EF",28)

Entschuldigung für die Formatierung.

1
Phil