선행 0을 추가하는 방법?


351

다음과 같은 데이터 세트가 있습니다.

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

각 동물 ID 앞에 0을 추가하고 싶습니다.

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

관심을 끌기 위해 동물 ID 앞에 2 개 또는 3 개의 0을 추가해야하는 경우 어떻게해야합니까?


6
동물 ID 앞에 n 개의 0을 추가한다고 가정 해 봅시다data$anim = paste(rep(0, n), data$anim, sep = "")
Ramnath

2
"0을 추가하고 싶다"고 말할 때 아마도 데이터 자체에 0으로 채워지는 정수를 추가하기 위해 정수 열을 문자열 / 범주로 변환하고 싶지 않을 것입니다. 정수를 유지하고 선행 0 만 인쇄 하려고합니다. 출력을 렌더링 할 때 .
smci

답변:


552

짧은 버전 : 사용 formatC 또는을sprintf .


더 긴 버전 :

선행 0을 추가하는 것을 포함하여 숫자 서식을 지정할 수있는 몇 가지 기능이 있습니다. 어떤 형식이 가장 적합한 지 다른 형식에 따라 다릅니다.

모든 값은 같은 자릿수를 갖기 때문에 문제의 예는 매우 쉽습니다. 따라서 10 너비 8의 거듭 제곱을 만드는 더 어려운 예를 시도해 봅시다.

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

paste(그리고 변형 paste0)은 종종 당신이 처음 접하는 문자열 조작 함수입니다. 그것들은 실제로 숫자를 조작하기 위해 고안된 것은 아니지만 그것을 위해 사용될 수 있습니다. 우리가 항상 단일 0을 앞에 붙여야하는 간단한 경우에 paste0가장 좋은 솔루션입니다.

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

숫자에 가변 자릿수가있는 경우, 앞에 붙일 0의 수를 수동으로 계산해야합니다.


str_padfrom stringr과 (와) 유사한 방식으로 작동 paste하여 물건을 채우고 싶다는 것을 더욱 명확하게합니다.

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

다시 말하지만, 실제로 숫자와 함께 사용하도록 설계되지 않았으므로 어려운 경우에는 약간의 생각이 필요합니다. "폭이 0 인 패드 8"이라고 말할 수 있어야하지만 다음 출력을보십시오.

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

과학적 페널티 옵션 을 설정하여 숫자가 항상 과학적 표기법이 아닌 고정 된 표기법을 사용하여 형식화되도록해야합니다.

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

stri_pad에서 stringi정확히 같은 작품 str_pad에서 stringr.


formatCC 함수에 대한 인터페이스 printf입니다. 이를 사용하려면 해당 기본 기능의 arcana에 대한 지식이 필요합니다 (링크 참조). 이 경우 중요한 점은 "정수" 에 대한 width논거이며format"d""0" flag 앞에 붙이는 제로합니다.

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"

너비를 변경하면 땜질하기 쉽고 다른 형식 변경을 수행 할 수있을만큼 강력하기 때문에이 솔루션은 제가 가장 좋아하는 솔루션입니다.


sprintf동일한 이름의 C 함수에 대한 인터페이스입니다. 비슷 formatC하지만 다른 구문으로.

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

가장 큰 장점은 sprintf더 긴 텍스트 비트 안에 서식이 지정된 숫자를 포함시킬 수 있다는 것입니다.

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

goodside의 답변 도 참조하십시오 .


완전성을 위해 때로는 유용하지만 0을 추가하는 방법이없는 다른 서식 기능을 언급 할 가치가 있습니다.

format, 숫자에 대한 메소드를 사용하여 모든 종류의 오브젝트를 형식화하는 일반 함수입니다. 그것은 약간 비슷 formatC하지만 또 다른 인터페이스와 함께 작동합니다 .

prettyNum수동 축 눈금 레이블을 만들기위한 또 다른 서식 기능입니다. 특히 광범위한 숫자에 적합합니다.

scales패키지에는 percent, date_formatdollar특수 형식 유형 과 같은 여러 기능이 있습니다.


3
큰 도움을 주셔서 감사합니다. 나는 formatC를 사용하여 내 애니메에 선행 0을 추가했으며 잘 작동했습니다.
baz

2
formatC (숫자 또는 벡터, 너비 = 6, 형식 = "d", 플래그 = "0")가 제대로 작동했습니다 (R 버전 3.0.2 (2013-09-25)). 감사.
Mohamad Fakih

1
위에서 설명한 방식으로 formatC ()를 사용하면 효과가 없었습니다. 0 대신 공백을 추가했습니다. 내가 뭐 잘못 했어요? R 버전 3.1.1을 사용하고 있습니다.
user1816679

2
@ user1816679 잊어 버린 것 같습니다 flag = "0".
Richie Cotton

1
?sprintf도움말 페이지 의 세부 사항 섹션에서이를 설명합니다. "mn : 필드 너비 (m)와 정밀도 (n)를 나타내는 두 개의 숫자가 마침표로 구분됩니다."
Richie Cotton

215

의 자릿수에 관계없이 작동하는 일반 솔루션의 경우이 함수를 data$anim사용하십시오 sprintf. 다음과 같이 작동합니다.

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

귀하의 경우에는 다음을 원할 것입니다. data$anim <- sprintf("%06d", data$anim)


14
참고 sprintf문자열 (문자)로 숫자 변환합니다.
aL3xa

답변 해주셔서 감사합니다. 13 자리 숫자를 14 자리로 만들고 싶습니다 (앞에 0을 더함). 이 경우이 기능이 작동하지 않는 것 같습니다. 오류가 발생합니다. sprintf ( "% 020d", 4000100000104)의 오류 : 잘못된 형식 '% 020d'; 숫자 개체에는 % f, % e, % g 또는 % a 형식을 사용하십시오. 어떠한 제안?
Rotail 2012 년

시도 : sprintf ( "% 014.0f", 4000100000104)
Stewart Macdonald

R 3.4.1
Frank FYC에

네 그렇습니다. 버전 1.5.0부터 변경되지 않았습니다.
dash2

32

@goodside의 응답에서 확장 :

경우에 따라 문자열을 0으로 채울 수 있습니다 (예 : fips 코드 또는 기타 숫자와 같은 요소). OSX / Linux에서 :

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

그러나 여기서 논의 된 sprintf()OS의 C sprintf()명령을 호출 하기 때문에 Windows 7에서는 다른 결과가 나타납니다.

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

따라서 Windows 시스템에서 해결 방법은 다음과 같습니다.

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

1
어떤 이유로 든이 솔루션은 더 이상 Linux에서 작동하지 않습니다. @ kdauria 's str_pad는 이제 나의 갈 곳입니다.
metasequoia

25

str_pad로부터 stringr패키지 대안입니다.

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

4
str_pad예기치 않은 결과가 발생할 수 있으므로 주의하십시오 . i.num = 600000; str_pad(i.num, width = 7, pad = "0") "0600000"이 아닌 "006e + 05"를 제공합니다
Pankil Shah

2

일반화 가능한 기본 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)

나는 좋아 sprintf하지만 다음과 같은 경고가 있습니다.

그러나 실제 구현은 C99 표준을 따르며 세부 사항 (특히 사용자 오류의 동작)은 플랫폼에 따라 다를 수 있습니다


1

다음은 때때로 숫자처럼 보일 수 있고 Excel과 같은 많은 응용 프로그램이 선행 0을 손상시키고 제거하거나 과학적 표기법으로 변환하는 CUSIP 와 같은 문자열에 선행 0을 추가하는 또 다른 대안입니다 .

@metasequoia가 제공 한 답변을 시도했을 때 반환 된 벡터에는 0s가 아닌 선행 공백이있었습니다 . 이것은 @ user1816679 언급 같은 문제이었다 - 그리고 주위에 따옴표를 제거 0또는에서 변화 %d%s하나 차이를 만들지 않았다. 참고로, 우분투 서버에서 실행되는 RStudio 서버를 사용하고 있습니다. 이 작은 2 단계 솔루션은 저에게 효과적이었습니다.

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

패키지 %>%에서 파이프 함수를 사용하면 magrittr다음과 같이 보일 수 있습니다.

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

단일 기능 솔루션을 선호하지만 작동합니다.


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

그냥은 paste0(0, data$anim)벌금을 작동합니다.
dash2

0

숫자 문자열이 일관성을 유지하려는 다른 상황에서는 함수를 만들었습니다.

누군가 이것이 유용하다는 것을 알 수 있습니다.

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)

형식에 대해 죄송합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.