2017-11-09 9 views
5

私は、文字列のベクトルを持って、次の形式で:データフレームの位置に基づいてstringをnumberに置き換えるにはどうすればいいですか?

strings <- c("UUDBK", "KUVEB", "YVCYE") 

私もこのようなデータフレームを持っている:

replacewith <- c(8, 4, 2) 
searchhere <- c("UUDBK, YVCYE, KUYVE, IHVYV, IYVEK", "KUVEB, UGEVB", "KUEBN, IHBEJ, KHUDN") 
dataframe <- data.frame(replacewith, searchhere) 

私は、文字列ベクトルは、その中に値に置き換えられたいですこのデータフレーム内の対応する「replacewith」列。現在、私はそれをやっている方法は次のとおりです。

final <- sapply(as.character(strings), function(x) 
as.numeric(dataframe[grep(x, dataframe$searchhere), 1])) 

しかし、これは非常に計算重い長さ10^9と文字ベクトルでこれをやっていることです。

これを行うにはどうすればよいですか?

ありがとうございます!

答えて

2

@ AntoniosKの考え方と同様に、代わりにhashmapを使用して文字列を値にマッピングします。それは非常に高速ですのでhashmapは、内部Rcppで実装されています

library(hashmap) 
library(tidyr) 

search_replace = separate_rows(dataframe, searchhere) 

search_hash = hashmap(search_replace[,2], search_replace[,1]) 

search_hash[[strings]] 

結果:

> search_hash 
## (character) => (numeric) 
##  [KHUDN] => [+2.000000] 
##  [KUEBN] => [+2.000000] 
##  [UGEVB] => [+4.000000] 
##  [KUVEB] => [+4.000000] 
##  [IYVEK] => [+8.000000] 
##  [IHVYV] => [+8.000000] 
##  [...] => [...] 

> search_hash[[strings]] 
[1] 8 4 8 

ベンチマーク:

> OP_func = function(){sapply(as.character(strings), function(x) 
    as.numeric(dataframe[grep(x,dataframe$searchhere), 1]))} 

Unit: microseconds 
          expr  min  lq  mean median  uq  max neval 
         OP_func() 121.191 124.9410 190.36472 129.8760 151.193 3370.047 100 
d[d$searchhere %in% strings, ] 36.714 40.6605 52.85093 43.8185 61.583 147.246 100 
     search_hash[[strings]] 14.212 18.1590 25.05212 21.5150 29.608 58.820 100 

はまたAntoniosKのソリューション@ませんのでご注意をstringsに重複がある場合は動作しますhashmapは、正しい位置にある各要素の正しいマッピングを返します。

例:

> strings_large = sample(search_replace$searchhere, 100, replace = TRUE) 
> strings_large 
    [1] "YVCYE" "KUVEB" "KUYVE" "KHUDN" "KUYVE" "KHUDN" "KUEBN" "UUDBK" "KHUDN" "YVCYE" "IYVEK" 
[12] "KUEBN" "KHUDN" "IHBEJ" "YVCYE" "KHUDN" "KUEBN" "UGEVB" "UUDBK" "KUYVE" "KHUDN" "IHBEJ" 
[23] "IHVYV" "KUVEB" "IYVEK" "KHUDN" "KHUDN" "KUYVE" "YVCYE" "UUDBK" "KUYVE" "IHVYV" "KUYVE" 
[34] "KUEBN" "KUYVE" "UUDBK" "KUYVE" "KUVEB" "KUVEB" "YVCYE" "KUYVE" "KHUDN" "KUVEB" "YVCYE" 
[45] "IHBEJ" "YVCYE" "KHUDN" "UUDBK" "KUEBN" "IYVEK" "IHVYV" "UUDBK" "KUYVE" "KUEBN" "YVCYE" 
[56] "UGEVB" "YVCYE" "KUYVE" "IHVYV" "KUEBN" "IHVYV" "IHBEJ" "KUVEB" "IHVYV" "KUYVE" "KUEBN" 
[67] "IYVEK" "KUVEB" "KUEBN" "UGEVB" "KUEBN" "KUVEB" "IHBEJ" "KUYVE" "YVCYE" "YVCYE" "IHVYV" 
[78] "YVCYE" "KHUDN" "KHUDN" "YVCYE" "IYVEK" "KUYVE" "KHUDN" "UGEVB" "YVCYE" "IHVYV" "KUVEB" 
[89] "IYVEK" "KUEBN" "UGEVB" "UUDBK" "IYVEK" "IHBEJ" "IHBEJ" "UUDBK" "KUVEB" "UGEVB" "IYVEK" 
[100] "IYVEK" 

> search_hash[[strings_large]] 
    [1] 8 4 8 2 8 2 2 8 2 8 8 2 2 2 8 2 2 4 8 8 2 2 8 4 8 2 2 8 8 8 8 8 8 2 8 8 8 4 4 8 8 2 4 8 
[45] 2 8 2 8 2 8 8 8 8 2 8 4 8 8 8 2 8 2 4 8 8 2 8 4 2 4 2 4 2 8 8 8 8 8 2 2 8 8 8 2 4 8 8 4 
[89] 8 2 4 8 8 2 2 8 4 4 8 8 
2
library(tidyr) 

strings <- c("UUDBK", "KUVEB", "YVCYE") 

replacewith <- c(8, 4, 2) 
searchhere <- c("UUDBK, YVCYE, KUYVE, IHVYV, IYVEK", "KUVEB, UGEVB", "KUEBN, IHBEJ, KHUDN") 
dataframe <- data.frame(replacewith, searchhere, stringsAsFactors = F) 

# split strings to one row each 
# like a look up table 
d = separate_rows(dataframe, searchhere) 

# get the number based on the look up table 
d[d$searchhere %in% strings,] 

# replacewith searchhere 
# 1   8  UUDBK 
# 2   8  YVCYE 
# 6   4  KUVEB 

この形式が気に入っているかどうかは不明ですが、いつでも変更できます。

+0

'final'が、私は何かが足りないだけUUDBK KUVEB YVCYE 8 4 8アム示して? – AntoniosK

+0

@AntoniosK元の質問で私の変数finalについて話していますか?これが望ましい出力です。これは、置換された値を持つベクトルです。 –

+0

これは@RichScrivenへの返事でした。私のコードはあなたのために働くのですか? – AntoniosK

関連する問題