r strsplitをベクトル化する方法は?
-
27-09-2019 - |
質問
使用する関数を作成するとき strsplit
, 、ベクトル入力は必要に応じて動作しません、そして sapply
使用する必要があります。これは、リストの出力によるものです strsplit
生成。プロセスをベクトル化する方法はありますか?つまり、関数は入力の各要素のリスト内の正しい要素を生成しますか?
たとえば、文字ベクトルの単語の長さをカウントするには:
words <- c("a","quick","brown","fox")
> length(strsplit(words,""))
[1] 4 # The number of words (length of the list)
> length(strsplit(words,"")[[1]])
[1] 1 # The length of the first word only
> sapply(words,function (x) length(strsplit(x,"")[[1]]))
a quick brown fox
1 5 5 3
# Success, but potentially very slow
理想的には、ようなものです length(strsplit(words,"")[[.]])
どこ .
入力ベクトルの関連部分であると解釈されます。
解決
一般に、最初からベクトル化された関数を使用してみてください。使用 strsplit
その後、何らかの反復が必要になることがよくあります(これは遅くなります)ので、可能であれば避けてください。あなたの例では、使用する必要があります nchar
代わりは:
> nchar(words)
[1] 1 5 5 3
より一般的には、その事実を利用してください strsplit
リストを返して使用します lapply
:
> as.numeric(lapply(strsplit(words,""), length))
[1] 1 5 5 3
または、anを使用します l*ply
家族の機能 plyr
. 。例えば:
> laply(strsplit(words,""), length)
[1] 1 5 5 3
編集:
敬意を表して ブルームズデイ, 、ジョイスのユリシーズを使用して、これらのアプローチのパフォーマンスをテストすることにしました。
joyce <- readLines("http://www.gutenberg.org/files/4300/4300-8.txt")
joyce <- unlist(strsplit(joyce, " "))
私はすべての言葉を持っているので、私たちは私たちのカウントをすることができます:
> # original version
> system.time(print(summary(sapply(joyce, function (x) length(strsplit(x,"")[[1]])))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
2.65 0.03 2.73
> # vectorized function
> system.time(print(summary(nchar(joyce))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
0.05 0.00 0.04
> # with lapply
> system.time(print(summary(as.numeric(lapply(strsplit(joyce,""), length)))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
0.8 0.0 0.8
> # with laply (from plyr)
> system.time(print(summary(laply(strsplit(joyce,""), length))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
17.20 0.05 17.30
> # with ldply (from plyr)
> system.time(print(summary(ldply(strsplit(joyce,""), length))))
V1
Min. : 0.000
1st Qu.: 3.000
Median : 4.000
Mean : 4.666
3rd Qu.: 6.000
Max. :69.000
user system elapsed
7.97 0.00 8.03
ベクトル化された関数と lapply
オリジナルよりもかなり高速です sapply
バージョン。すべてのソリューションは、同じ答えを返します(要約出力で見られるように)。
どうやら最新バージョンの plyr
より速いです(これはわずかに古いバージョンを使用しています)。
所属していません StackOverflow