r format number - ¿Cómo agregar ceros iniciales?




4 Answers

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.

decimal date

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?




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"



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



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




Related