Rでの計算速度?


16

私は、現在の大規模な確率モデルの1つをSASから新しい言語に移行することを任されました。個人的には、伝統的なコンパイル言語を好みますが、PIは私が使用したことのないRをチェックアウトすることを望んでいます。SASからモデルを取得する動機は、(1)SASが高価であるため多くの人がモデルにアクセスできないこと、(2)インタプリタ言語から遠ざかりたい、(3)SASが遅いことです。持っているモデルのタイプ。

(1)の場合、明らかにRは自由である必要性を満たします。(2)の場合、理想的には実行可能ファイルを作成したいのですが、Rは通常スクリプト言語として使用されます。誰かが最近Rコンパイラを発表したようです。これは好評ですか?使いやすいですか?ユーザーにRを強制的にダウンロードさせたくないのです。(3)の場合、SASの問題は、データセットのI / Oの書き込みと読み取りに費やされる時間です。このモデルは計算集約型であり、多くの場合、実行時間によって制限されます。(たとえば、週末に誰かのコンピューターをハイジャックして実行することは珍しくありません。)Fortranで構築された同様のモデルには、すべての作業がメモリー内で行われるため同じ問題はありません。Rはどのように機能しますか?データステップで機能するという点で、SASと同じでしょうか。ファイルの読み書き?または、メモリ内で配列を操作できますか?


通常、すべての作業を1つのデータステップで実行することで、sasを高速化できます。これにより、事実上データを一度しか読み取らないため、I / O時間を短縮できます。多くの手順を使用すると、速度が低下します。たとえば、proc glmまたはproc logisticの呼び出しを繰り返しモデリングする場合(ブートストラップなど)、大量のproc呼び出しを呼び出す(マクロ%doループを使用する)よりも、巨大なデータセットを作成してbyステートメントを使用する方が高速です。あなたもSASをプログラム場合は、少なくともではない、もう他のソフトウェアよりも(これはファイルを読み込み、outputingに、実行時に問題がすべきではない
probabilityislogic

また、あなたはR.で行列を使用する方法と同様の方法で、SASデータの手順で一時的な配列を使用することができます
probabilityislogic

回答:


18

Rはメモリ内で動作します-そのため、データの大部分はメモリに収まる必要があります。

コンパイラパッケージは、あなたが考えていることを考えている場合(Rが提供するルークティアニーのコンパイラパッケージ)、従来の意味でのコンパイル言語(C、Fortran)とは異なります。これは、Java VMによって実行されるJavaバイトコードまたはEmacs LISPコードのバイトコンパイルという意味でのRのバイトコンパイラです。Rコードをマシンコードにコンパイルするのではなく、Rコードをバイトコードに準備するので、生のRコードを解釈するよりも効率的に使用できます。

Fortranの形式が整っていれば、おそらく両方の長所を持つことができます。RはコンパイルされたFortranルーチンを呼び出すことができます。


ありがとう!素晴らしいRグラフィックを持ち、コンパイルされたFortranルーチンを呼び出すことができることを知ってうれしいです。これが答えかもしれません!
メリッサ

2
メモリに関するGavinのメモを拡張するだけです。大きなデータセットを使用している場合は、このCRANタスクビューの大容量メモリに関するセクションを参照してください:cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen

1
また、Rcppを使用してパフォーマンスを徐々に向上させることができることに注意することも重要だと思います。
ブランドンバーテルセン

Rcppは、Rで使用するためにC ++をラップするのに役立ちます。プロセスを(非常に)支援しますが、Rの基本ツールを使用して、コンパイルされたコードを呼び出しています。OPにすでにFortranコードまたはFortranスキルがある場合、Rcppはあまり使用されない可能性があります。
モニカの復職-G.シンプソン

13

私はSAS15年間使用してきましたがR、過去6か月間真剣に使用を開始し、その数年前からいじり回しました。プログラミングの観点からR は、データ操作を直接行います。これらは必要ないため、同等DATAまたはPROC SQL手順はありません(後者SASは、管理データなどの外部データソースから行うデータ操作が多い場合により効率的です)。これは、今私はそれのこつを得ていることを意味します、データ操作はより速く、Rはるかに少ないコードを必要とします。

私が遭遇した主な問題はメモリです。すべてのRパッケージでWEIGHT型指定が許可されているわけではないためSASFREQor REPLICATEステートメントで使用される変数を含むデータセットがある場合、問題が発生する可能性があります。Rのパッケージffbigmemoryパッケージを見てきましたが、すべてのRパッケージとの互換性はないようです。そのため、比較的一般的ではない分析が必要な非常に大きなデータセットがあり、集約されている場合、メモリに問題がある可能性があります。

自動化のために、もしあればSAS macros、同等のものをプログラムしRてバッチとして実行できるはずです。

コーディングのためにR、私はNotepad++言語を使用し設定していましたがR、今はの喜びを発見していR Studioます。これらの製品は両方とも無料であり、改善されたSAS構文GUIのように言語マークアップを行います(構文画面はでのみ使用したことがありますSAS)。

からにスワッピングする人向けのウェブサイトと関連書籍があります。私はそれらがいくつかのコマンドを。SASRSASR

アップデート:に来たときにナット私を運転した一つのことRつまりRすべてが(データセットであると仮定しないdata frameR用語)、それは方法で統計パッケージことはないので、SASSPSSStata、などです。したがって、たとえば、ベクトル(またはマトリックス)ifを含むifステートメントのヘルプを取得し続けたのに、で動作するifステートメントが必要だったため、ステートメントが機能するまでに時間がかかりましたdata frames。そのため、ヘルプページは、通常よりも注意深く読む必要があります。実行するコマンドが、使用しているデータオブジェクトタイプで動作することを確認する必要があるためです。

新しいRコマンド(提供されたパッケージの分析方法など)を学習するとき、まだ私を夢中にさせているのは、コマンドのヘルプが完全に自己完結していないことが多いということです。ヘルプページにアクセスして、コマンドと...その中に含まれていることが多い使用上の注意を学習しようとします。時々、どこに行くことができるか、またはすべきかを解決しようとすると...、再帰ループに陥ります。ヘルプノートの相対的な簡潔さは、SAS構文の詳細な例と、この例での研究の説明を含む実用的な例を提供するものであり、非常に大きな衝撃でした。


2
+1 統計ソフトウェアリソースへのリンクを収集したメタスレッドの更新を検討してください。RとSASには1つの返信があります。両方ともr4stats.comへのリンクがあれば有益です。(実際、このスレッドはFAQの一部です。最新で有用なものにしたいと考えています。)
whuber

1
Rには、RODBCドライバーまたはSQLiteを介したSQLアクセスをサポートするパッケージもあります。
-DWin

1
Rヘルプについてのあなたのコメントに同意します。何年も前に、Rメーリングリストの1つであなたが言っていることを本質的に指摘しました。応答は肯定的ではありませんでした。公平に言えば、私はおそらく(a)自分自身をあまり上手く表現せず、具体的な例を挙げず、(b)問題を追求しませんでした。要約すると、問題1は複雑すぎる例であり、関係のない概念が多すぎます。複雑な例は大丈夫ですが、簡単な例に従ってください。問題2は、例が何をするかについての注釈や説明がほとんどないことです。
ファヒムミタ

Rの「ヘルプ」については、上司が私に言ったことを思い出させます。「あなたはすでにコンピュータにあなたの隣に座っR知っている人でそれを実行してRを学ぶ」
probabilityislogic

そして、他の皆のために本とStack Overflowがあります。はい、Rを自分で学ぶのはかなり難しいです。少なくとも私にとってはそうでした。
ミシェル

10

Rはプログラミング言語です。データステップでは機能しません。プログラミング言語であり、あなたの欲望の奴隷であり、中括弧とコロンの言語で表現されているからです。

FortranやCのように考えてください。ただし、暗黙のベクトル化により配列をループする必要がなく、動的メモリ管理によりmalloc()や配列サイズを宣言する必要がありません。

ほとんどすべての作業をメモリ内で行いますが、ファイルの一部を読み取り、それを破棄し、結果の一部を吐き出し、次のビットを読み取りたい場合は、先に進んでRプログラムを作成します。それをします。

モデルは計算集約的であるが、I / OのためにSASが遅いと言うことにあなたは矛盾します。

Fortranで既に似たようなものがあり、インタープリター言語から離れたいと言ったら、Fortranでも同じようにしないのはなぜですか?

Rコンパイラーによって速度が向上する可能性がありますが、Rコードが適切に作成されていれば、CやFortranで作成するのとは異なり、あまり大きなものは得られません。


ああ、私は自分自身をうまく説明しませんでした。データセットの操作に集中しており、SASではI / Oに費やす時間が長すぎます。私の最初の提案はFortranでしたが、PIは私たちがRに切り替えることに興味を持っているので、彼は私にそれをチェックしてほしかったです。ありがとう!
メリッサ

7

デフォルトでは、SASはメモリよりも大きいモデルで動作することを理解していますが、biglmやffなどのパッケージを特に使用しない限り、Rには当てはまりません。

ただし、ベクトル化できるRで配列作業をしている場合は非常に高速です-場合によってはCプログラムの半分の速度ですが、ベクトル化できないことをしている場合は、スロー。例を挙げましょう:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Nを10倍から100,000倍に増やしたとき、20分後にテスト4をあきらめましたが、テスト1:3にはそれぞれ61、3 、および37 ミリ秒かかりました

N = 10,000,000の場合、テスト1:3の時間は3.3秒、0.6秒、および1.6秒です。

これはi7ラップトップで行われ、N = 1000万で480mbであったことに注意してください。メモリは問題ではありませんでした。

32ビットウィンドウを使用するユーザーの場合、メモリの量に関係なくRには1.5gbのメモリ制限がありますが、64ビットウィンドウまたは64ビットLinuxにはそのような制限はありません。最近のメモリは、1時間のコストと比較して非常に安いため、これを回避するために時間を費やすのではなく、メモリを追加購入するだけです。ただし、これはモデルがメモリに収まることを前提としています。


1
(+1)有益なイラストを提供してくれてありがとう、Sean!
whuber

3

(2)理想的には、実行可能ファイルを作成したいのですが、Rは通常、スクリプト言語として使用されます

はい、これがRに移行する正当な理由です。Rパッケージを記述することの目的は、ユーザーがRが提供する他のツールと簡単に対話できるようにすることです。これが重要だと思わない場合は、C / C ++またはお気に入りのコンパイル済み言語に固執してください。

警告を追加します。あなたはすでにプログラマーです。Rを学ぶことは簡単かつ迅速になります。効率的なRプログラミングの学習は長くなります。Rは解釈されるため、O漸近的な複雑さは、大きくても小さくてもかまいません。たとえば、データの実行に関心がある場合は、を使用しrle()ます。高速になります(プリコンパイルされた関数)。まったく同じアルゴリズムをスクリプト化すると、遅くなります(解釈されます)。これは基本的な例です:ループの解釈を避け、プリコンパイルされた関数がすべての仕事をするように、ベクトルと行列を使用する多くのトリックがあります。

だから非常に注意してください。最初の試行後、Rに嫌悪感を抱くようになります。これは、遅い、奇妙な構文などに気付くからです。一度理解すれば、非常に効率的なツールになります。C / C ++コーディングの予備段階としてRでメソッドをスクリプト化することで終了することさえできます。最終段階では、RのAPIを学習してプリコンパイル済み関数を作成し、Rウィザードになります:)


2

明らかに、メモリ内の配列操作はSASにとって大きなことです。Rに関する詳細はわかりませんが、R、ff、およびbigmemoryのメモリ拡張パッケージはデータをメモリからディスクに移動するため、Rはデフォルトでメモリで動作すると推測します。あなたが速度またはメモリ使用量を改善したい場合、私はあなたのためのポインタを持っています。速度を改善するには、まずRを意図したとおりに使用する必要があります。つまり、コードをベクトル化し、バイトコードコンパイルを使用します。(また:メモリーコピー操作を可能な限り避けてください。)次に、提供されているコードプロファイラーRprof()を使用してコード内の遅いパッチを識別し、必要に応じてCまたはC ++で書き換えます。より多くのメモリが必要な場合、read.table()関数でskip引数を使用してデータを一度にチャンクで読み込むことができます。また、Rにデータベース操作ユーティリティを追加するRMySQLなどのパッケージを使用することもできます。さらに多くのメモリが必要で、同時に速度を落とす余裕がある場合は、snowパッケージを使用してRを並行して実行できます。(これに関する詳細は、昨年末に出版されたNorman Matloff著の「The Art of R Programming」にあります。ここで言及されているパッケージの詳細はオンラインで見つけることができます。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.