4


私は (html-) テキストを持っており、それを ä、ü、ö などの実際の文字に変更したいと考えてöいます。そうしないと、xml-package がそれを受け入れないからです。

そこで、置換テーブル ( link1 、 link2 ) を循環し、特殊文字を sp によって特殊文字に置き換える小さな関数を作成ました... 関数は次のようになります (loonger のみ):

html.charconv <- function(text){
    replacer <- matrix(c(
    "Á",    "&Aacute;",
    "á",    "&aacute;",
    "Â",    "&Acirc;",
    "â",    "&acirc;",
    "´",    "&acute;"
    )
    ,ncol=2,byrow=T)

    for(i in 1:length(replacer[,1])){
        text <- str_replace_all(text,replacer[i,2],replacer[i,1])
    }
    text
}

どうすればこれをスピードアップできますか? ベクトル化について考えましたが、各サイクルでは最後のサイクルの結果が開始点であるため、解決策はありませんでした。

4

4 に答える 4

8

楽しみのために、ここに に基づくバージョンがありRcppます。

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
CharacterVector rcpp_conv( 
    CharacterVector text, CharacterVector old , CharacterVector new_){

    int n  = text.size() ;
    int nr = old.size() ;

    std::string buffer, current_old, current_new ;
    size_t pos, current_size ; 
    CharacterVector res(n) ;

    for( int i=0; i<n; i++){
        buffer = text[i] ;
        for( int j=0; j<nr; j++){
             current_old = old[j] ;
             current_size = current_old.size() ;
             current_new = new_[j] ;
             pos = 0 ;   
             pos = buffer.find( current_old ) ;
             while( pos != std::string::npos ){
                 buffer.replace( 
                     pos, current_size, 
                     current_new
                 ) ;
                 pos = buffer.find( current_old ) ;
             }
        }
        res[i] = buffer ;
    }
    return res ;
}

これにより、パフォーマンスが大幅に向上します。

> microbenchmark(
+     html.fastconv( sometext,oldchar,newchar),
+     html.fastconvJC(sometext, oldchar, newchar),
+     rcpp_conv( sometext, oldchar, newchar)
+ )
Unit: microseconds
                                         expr    min      lq   median      uq
1   html.fastconv(sometext, oldchar, newchar) 97.588 99.9845 101.4195 103.072
2 html.fastconvJC(sometext, oldchar, newchar) 19.945 23.3060  25.8110  28.134
3       rcpp_conv(sometext, oldchar, newchar)  4.047  5.1555   6.2340   9.275
      max
1 256.061
2  40.647
3  25.763

Rcpp::Stringから入手できる機能に基づく実装を次に示しRcpp >= 0.10.2ます。

class StringConv{
public:
    typedef String result_type ;
    StringConv( CharacterVector old_, CharacterVector new__): 
        nr(old_.size()), old(old_), new_(new__){}

    String operator()(String text) const {
        for( int i=0; i<nr; i++){
            text.replace_all( old[i], new_[i] ) ;
        }     
        return text ;
    }

private:
    int nr ;
    CharacterVector old ;
    CharacterVector new_ ;
} ;

// [[Rcpp::export]]
CharacterVector test_sapply_string( 
   CharacterVector text, CharacterVector old , CharacterVector new_
){
   CharacterVector res = sapply( text, StringConv( old, new_ ) ) ;
   return res ;
}  
于 2012-11-27T13:49:05.353 に答える
8

関数を少し異なる方法で構築することで、大幅な高速化を実現できます。テキスト ツールは忘れてください。基本的にあなた:

  1. 文字列を分割する
  2. 必要な文字を一致させ、新しい文字に置き換えます
  3. すべてをもう一度貼り付けます

次の関数でそれを行うことができます:

html.fastconv <- function(x,old,new){
    xs <- strsplit(x,"&|;")
    old <- gsub("&|;","",old)
    xs <- lapply(xs,function(i){
        id <- match(i,old,0L)
        i[id!=0] <- new[id]
        return(i)
    })
    sapply(xs,paste,collapse="")
}

これは次のように機能します。

> sometext <- c("&Aacute;dd som&aacute; le&Acirc;tter&acirc; acute problems et&acute; cetera",
+  "&Aacute;dd som&aacute; le&Acirc;tter&acirc; acute p ..." ... [TRUNCATED] 

> newchar <- c("Á","á","Â","â","´")

> oldchar <- c("&Aacute;","&aacute;","&Acirc;","&acirc;","&acute;")
> html.fastconv(sometext,oldchar,newchar)
[1] "Ádd somá leÂtterâ acute problems et´ cetera" "Ádd somá leÂtterâ acute problems et´ cetera"

記録のために、いくつかのベンチマーク:

require(rbenchmark)
benchmark(html.fastconv(sometext,oldchar,newchar),html.charconv(sometext),
     columns=c("test","elapsed","relative"),
     replications=1000) 
                                       test elapsed relative
2                   html.charconv(sometext)    0.79    5.643
1 html.fastconv(sometext, oldchar, newchar)    0.14    1.000
于 2012-11-27T12:26:40.783 に答える
5

36,000 のファイルの読み取りと書き込みがボトルネックであり、R でコーディングする方法ではあまり役に立たないと思います。しばらく時間がかかるものもあります。あなたの関数は正しく動作するように見えます。ただ実行させてください。あなたが行うことができるいくつかの小さな改善があります。

replacer <- matrix(c(
    "Á",    "&Aacute;",
    "á",    "&aacute;",
    "Â",    "&Acirc;",
    "â",    "&acirc;",
    "´",    "&acute;"
    )
    ,ncol=2, byrow=T)

html.fastconvJC <- function(x,old,new){
    n <- length(new)
    s <- x #make a copy cause I'm scared of scoping in R :)
    for (i in 1:n) s <- gsub(old[i], new[i], s, fixed = TRUE)
    s
    }

# borrowing the strings from Joris Meys
benchmark(html.fastconvJC(sometext, replacer[,2], replacer[,1]),
      html.charconv(sometext), columns = c("test", "elapsed", "relative"),
      replications=1000)

                                                     test elapsed relative
2                                 html.charconv(sometext)   0.727    17.31
1 html.fastconvJC(sometext, replacer[, 2], replacer[, 1])   0.042     1.00

そして、彼らは私が思っていたよりもスピードを上げました。そのスピードアップの大部分はfixed = TRUE.

これで全体的な速度が大幅に向上しない場合は、ボトルネックが別の場所にあることがわかります。おそらくファイルの読み取りと書き込みです。ソリッド ステート ドライブまたは RAID ドライブを使用していない限り、これを並行して実行しても速度は向上せず、速度が低下するだけです。

于 2012-11-27T12:10:23.703 に答える
-1

私は plyr で試してみます:

input.data <- llply(input.files, html.charconv, .parallel=TRUE) 
于 2012-11-27T11:15:07.673 に答える