先行ゼロを追加する方法は?


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の前にゼロを追加したい:

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つのゼロを追加する必要がある場合はどうなりますか?


6
必要な動物IDの前にn個のゼロを追加するとしますdata$anim = paste(rep(0, n), data$anim, sep = "")
Ramnath

2
「ゼロを追加する」と言った場合、おそらくデータ自体の内部にゼロパディングを追加するために整数列を文字列/カテゴリに変換したくありません。それらを整数に保ち、先行ゼロのみを出力します。出力をレンダリングするとき
smci 2015

回答:


553

短いバージョン:formatCまたはを使用しますsprintf


長いバージョン:

先行ゼロの追加など、数値のフォーマットに使用できるいくつかの関数があります。どちらが最適かは、実行する他のフォーマットによって異なります。

質問の例は、すべての値が最初は同じ桁数であるため、非常に簡単です。10の累乗を8の累乗にするより難しい例を試してみましょう。

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

paste(そしてそのバリアントですpaste0)は、多くの場合、最初に遭遇する最初の文字列操作関数です。これらは実際には数値を操作するようには設計されていませんが、そのために使用できます。常に単一のゼロを付加する必要がある単純なケースでpaste0は、これが最良のソリューションです。

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

数字の桁数が可変である場合、先頭に追加するゼロの数を手動で計算する必要があります。これは、病的な好奇心からそれを実行するだけで十分なほど恐ろしいことです。


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_padstringi作品とまったく同じstr_padですstringr


formatCC関数へのインターフェースprintfです。それを使用するには、その基礎となる関数のアルカナの知識が必要です(リンクを参照)。この場合、重要な点は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の回答も参照してください。


完全を期すために、時々役立つ他のフォーマット関数に言及する価値がありますが、ゼロを付加する方法はありません。

format、数値のメソッドを使用して、あらゆる種類のオブジェクトをフォーマットするための汎用関数。はのようformatCに機能しますが、さらに別のインターフェースを備えています。

prettyNumは、主に手動の軸目盛りラベルを作成するための、さらに別のフォーマット関数です。これは、広範囲の数値に対して特に効果的です。

scalesパッケージには、次のようないくつかの機能があるpercentdate_formatdollar専門家のフォーマットタイプのために。


3
多大なご協力ありがとうございました。formatCを使用して、アニメーションに先行ゼロを追加しましたが、うまく機能しました。
baz

2
formatC(数値またはベクトル、幅= 6、形式= "d"、フラグ= "0")はうまく機能しました(Rバージョン3.0.2(2013-09-25))。ありがとう。
Mohamad Fakih 2013年

1
上記の方法でformatC()を使用してもうまくいきませんでした。ゼロの代わりにスペースが追加されました。私は何か間違ったことをしましたか?Rバージョン3.1.1を使用しています。
user1816679 2014

2
@ user1816679忘れそうflag = "0"ですね。
リッチーコットン

1
?sprintfヘルプページの詳細セクションでこれについて説明しています。"mn:フィールド幅(m)と精度(n)を示す、ピリオドで区切られた2つの数値。"
リッチーコットン2016年

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 2011

答えてくれてありがとう。13桁の数字を14桁にしたい(先行ゼロを追加したい)。この関数は、この場合は機能しないようです。エラーが発生しました:sp​​rintf( "%020d"、4000100000104)のエラー:無効なフォーマット '%020d'; 数値オブジェクトには、フォーマット%f、%e、%gまたは%aを使用します。なにか提案を?
Rotail 2016

試してみてください:sprintf( "%014.0f"、4000100000104)
スチュワートマクドナルド

sprintfはR 3.4.1では使用できません
フランクFYC '19

はい、そうです。バージョン1.5.0以降は変更されていません。
dash2

32

@goodsideの返答を拡張する:

場合によっては、文字列にゼロを埋め込むこともできます(たとえば、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は私の行くところです。
メタセコイア2016

25

str_padstringrパッケージからは代替です。

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しても、違いはありませんでした。ちなみに、私はUbuntuサーバーで実行されているRStudioサーバーを使用しています。この小さな2ステップのソリューションは私にとってうまくいきました:

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

パッケージの%>%パイプ関数を使用すると、次のmagrittrようになります。

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

私は1つの機能のソリューションを好みますが、機能します。


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.