web-dev-qa-db-ja.com

先行ゼロを追加する方法

このようなデータのセットがあります。

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

299
baz

短縮形: formatC または sprintf を使用します。


長いバージョン:

先行ゼロの追加など、数値のフォーマット設定に使用できる機能がいくつかあります。どれが一番よいかは、他のどのフォーマットを実行したいかによって異なります。

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

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

paste(そしてその変種paste0)は、あなたが出会う最初の文字列操作関数です。それらは実際に数字を操作するために設計されていませんが、それらはそのために使用することができます。常に単一のゼロを付加しなければならない単純な場合には、paste0が最善の解決策です。

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

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


stringrstr_padpasteと同じように機能しますので、より明示的にパディングしたいと思うようになります。

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

繰り返しになりますが、実際には数値で使用するようには設計されていません。 「幅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"

stringi内のstri_padは、stringrstr_padとまったく同じように機能します。


formatCは、C関数 printf へのインターフェースです。それを使用するには、その基礎となる機能の基本的知識についてある程度の知識が必要です(リンクを参照)。この場合、重要な点はwidth引数です。formatは "integer"の場合は"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's answer もご覧ください。


完全を期すために、時折有用であるがゼロを前に付ける方法がない他のフォーマット関数を言及する価値があります。

formatは、任意の種類のオブジェクトをフォーマットするための一般的な関数です。数値用のメソッドもあります。これはformatCと少し似ていますが、さらに別のインターフェースで動作します。

prettyNumは、もう1つの書式設定関数です。主に手動軸の目盛りラベルを作成するためのものです。これは、広範囲の数値に対して特に効果的です。

scalesパッケージには、 percentdate_formatなどの関数がいくつかあります。 /] dollar スペシャリストフォーマットタイプの場合。

474
Richie Cotton

data$animの桁数に関係なく機能する一般的な解決策については、sprintf関数を使用してください。それはこのように動作します:

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

あなたの場合は、おそらく欲しいと思います:data$anim <- sprintf("%06d", data$anim)

200
goodside

@ 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"
29
metasequoia

stringrパッケージのstr_padが代替手段です。

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

これが一般化された基底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標準に準拠し、細かい詳細(特にユーザーエラーが発生した場合の動作)はプラットフォームによって異なります。

2
Tyler Rinker

CUSIPs のように、数字のように見えることがあり、Excelなどの多くのアプリケーションで破損して削除されることがある文字列に、先頭に0を付ける方法もあります先頭の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
Ursus Frost

数値文字列の一貫性を保ちたい他の状況では、関数を作りました。

誰かがこれが役に立つと思うかもしれません:

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)

フォーマットについては申し訳ありません。

1
Phil