number r formatting number-formatting r-faq

number - ¿Cómo agregar ceros iniciales?



format decimal in r (8)

Aquí hay otra alternativa para agregar el encabezado a 0 en cadenas como CUSIPs que a veces puede parecer un número y que muchas aplicaciones como Excel corromperán y eliminarán los 0 iniciales o los convertirán a notación científica.

Cuando probé la respuesta proporcionada por @metasequoia, el vector devuelto tenía espacios iniciales y no 0 s. Este fue el mismo problema mencionado por @ user1816679, y eliminar las comillas alrededor del 0 o cambiar de %d a %s tampoco hizo una diferencia. Para su información, estoy usando RStudio Server ejecutándose en un servidor Ubuntu. Esta pequeña solución de dos pasos funcionó para mí:

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

usando la función %>% pipe del paquete magrittr podría verse así:

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

Prefiero una solución de una función, pero funciona.

Tengo un conjunto de datos que se parece a esto:

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

Me gustaría añadir un cero antes de cada ID de animal:

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

Y, por el bien de los intereses, ¿qué sucede si necesito agregar dos o tres ceros antes de la identificación del animal?


Aquí hay una función de base R generalizable:

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)

Me gusta el sprintf pero viene con advertencias como:

sin embargo, la implementación real seguirá el estándar C99 y los detalles precisos (especialmente el comportamiento bajo error del usuario) pueden depender de la plataforma


Expandiendo en @ goodside''s repsonse:

En algunos casos, es posible que desee rellenar una cadena con ceros (por ejemplo, códigos Fips u otros factores de tipo numérico). En OSX / Linux:

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

Pero como sprintf() llama al comando sprintf() C del sistema operativo, que se explica here , en Windows 7 se obtiene un resultado diferente:

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

Así que en las máquinas con Windows la solución es:

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


La versión corta: use formatC o sprintf .

La versión más larga:

Hay varias funciones disponibles para formatear números, incluida la adición de ceros iniciales. Cuál es mejor depende de qué otro formato desea hacer.

El ejemplo de la pregunta es bastante sencillo ya que todos los valores tienen el mismo número de dígitos para comenzar, así que intentemos un ejemplo más difícil de hacer potencias de 10 de ancho 8 también.

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

paste (y su variante paste0 ) son a menudo las primeras funciones de manipulación de cadenas que se encuentran. Realmente no están diseñados para manipular números, pero pueden usarse para eso. En el caso simple en el que siempre tenemos que anteponer un solo cero, paste0 es la mejor solución.

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

En el caso de que haya un número variable de dígitos en los números, debe calcular manualmente cuántos ceros se deben agregar, lo que es lo suficientemente horrible como para que solo deba hacerlo por mórbida curiosidad.

str_pad de stringr funciona de manera similar a paste , por lo que es más explícito que quieres rellenar cosas.

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

Nuevamente, no está realmente diseñado para usar con números, por lo que el caso más difícil requiere un poco de reflexión. Deberíamos ser capaces de decir "pad con ceros al ancho 8", pero mira esta salida:

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

Debe configurar la option penalización científica para que los números siempre tengan el formato de notación fija (en lugar de notación científica).

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

stri_pad en stringi funciona exactamente igual que str_pad desde stringr .

formatC es una interfaz para la función C printf . Su uso requiere un cierto conocimiento de los arcanos de esa función subyacente (ver enlace). En este caso, los puntos importantes son el argumento de width , siendo el format "d" para "entero", y un flag "0" para anteponer ceros.

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"

Esta es mi solución favorita, ya que es fácil jugar con el cambio de ancho, y la función es lo suficientemente potente como para realizar otros cambios de formato.

sprintf es una interfaz para la función C del mismo nombre; como formatC pero con una sintaxis diferente.

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

La principal ventaja de sprintf es que puede incrustar números con formato dentro de bits de texto más largos.

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."

Véase también la respuesta de goodside .

Para completar, vale la pena mencionar las otras funciones de formato que en ocasiones son útiles, pero que no tienen un método para anteponer ceros.

format , una función genérica para formatear cualquier tipo de objeto, con un método para los números. Funciona un poco como formatC , pero con otra interfaz.

prettyNum es otra función de formato, principalmente para crear etiquetas de marca de eje manual. Funciona particularmente bien para una amplia gama de números.

El paquete de scales tiene varias funciones, como percent , date_format y dollar para tipos de formatos especializados.


Para otras circunstancias en las que desea que la cadena numérica sea consistente, hice una función.

Alguien puede encontrar esto útil:

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)

Lo siento por el formato.


Para una solución general que funcione sin importar cuántos dígitos estén en data$anim , use la función sprintf . Funciona así:

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

En su caso, probablemente desee: data$anim <- sprintf("%06d", data$anim)


str_pad del paquete stringr es una alternativa.

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


data$anim <- sapply(0, paste0,data$anim)