No.22125 R 文字列の連結  【明石】 2016/08/28(Sun) 21:02

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

Rプログラムについて,ご教示いただきたいことが出てきました。
何卒どうぞ,よろしくお願いいたします。

−−−

文字列ベクトルがあります。
簡単な例示です。
"1", "12", "12345", "1234", "123"

各要素の文字列の長さが不揃いですが,
最大の長さ(ここでは,要素"12345"の長さ5)にあわせて,
必要に応じて,先頭に"0"を連結して,
すべての要素の文字列の長さをあわせることを考えます。

出来上がりは,以下のようになります。

"00001", "00012", "12345", "01234", "00123"

ベクトルの長さが膨大(数十万件)なことから,効率的な方法を検討しています。

以下の2点について,ご教示をいただければ,大変に助かります。
(1) 先頭に"0"を連結する方法
(2) applyを使う方法

どうぞ,よろしくお願いいたします。

No.22126 Re: R 文字列の連結  【青木繁伸】 2016/08/29(Mon) 07:53

やりかたはいろいろあるけど,一番簡単(?)なのは sprintf を使うもの。
a = c("1", "12", "12345", "1234", "123")
n = max(nchar(a))
unname(sapply(a, function(b) sprintf("%0*s", n, b)))
* には n の値がつかわれ,実際には sprintf("%05s", b) と同じになる。
別の方法は
unname(sapply(a, function(b) paste(paste(rep("0", n-nchar(b)), collapse=""), b, sep="")))
のようなものがあるけど,見た目でもわかるが,sprintf を使うより実行時間は若干長い。
一番外側の unname は,文字列要素に名前が付くのをはぎ取るためなので,場合によっては不要。

No.22127 【御礼】 Re: R 文字列の連結  【明石】 2016/08/29(Mon) 08:51

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

今回も助けていただきました。
心から御礼を申し上げます。

例えば,"00000"という文字列を作成するには,
paste( rep( "0", 5) , sep="", collapse="" )
ということまでは自分でも分かりましたので,
個々の要素の文字列の長さから,先頭につける文字列の長さの計算はできました。

ただし,数十万件をループで回している方法は何とも回避したいと思っておりました。

大変に良い勉強をさせていただきました。
ありがとうございました。

No.22128 Re: R 文字列の連結  【青木繁伸】 2016/08/29(Mon) 11:27

sapply する必要はなかったですね。これだと unname も不要です。
a = c("1", "12", "12345", "1234", "123")
n = max(nchar(a))
sprintf("%0*s", n, a)

No.22129 Re: R 文字列の連結  【荒】 2016/08/29(Mon) 14:57

青木先生

横から失礼します。
R-3.2.5(Linux)では"0"の代わりに半角スペースで埋められてしまいました。

?sprintfで調べると
## Platform-dependent bad example from qdapTools 1.0.0:
## may pad with spaces or zeroes.
sprintf("%09s", month.name)
のような例が載っていました。

unname(sapply(a, function(b) paste(paste(rep("0", n-nchar(b)), collapse=""), b, sep="")))
では0で埋まりました。

参考までに。

No.22130 Special Thanks(Re: R 文字列の連結)  【明石】 2016/08/29(Mon) 20:07

青木先生,荒様

いつもお世話になり,ありがとうございます,明石と申します。

今回,大変に良い勉強をさせていただきました。

2つ,ご報告がございます。
・私は,Windows7,R-3.3.1の環境ですが,荒様と同じ結果となりました。
・100万件のデータに適用しましたが,爆走でした。

勇気を振り絞って,投稿させていただいて本当に良かった,と思いました。
ありがとうございました。

No.22131 Re: R 文字列の連結  【青木繁伸】 2016/08/29(Mon) 21:34

Platform dependent ですか。

もとの文字列に空白が含まれないならば,
gsub(" ", "0", sprintf("%0*s", n, a))
の方が速いかもしれません。

No.22135 Re: R 文字列の連結  【明石】 2016/08/30(Tue) 19:21

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

お示しをしてくださいました
gsub(" ", "0", sprintf("%0*s", n, a))
恐ろしいほど,早いです。

Rの文字列の連結は,paste()関数を使用することしか知りませんでしたので,
今回,sprintf()関数を教えていただきましたことを契機に,調べ物をしています。

大きな武器を得ました。
心から御礼を申し上げます。
ありがとうございました。

● 「統計学関連なんでもあり」の過去ログ--- 048 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る