web-dev-qa-db-ja.com

Rを使用する場合、SQLを使用する場合

多くの結合とルックアップテーブルを備えた中規模のデータベースがあります。

私はSQLよりもRに精通しており、MySQLを使用しています。

私の質問:

どの時点で、Rのデータサブセット機能を優先してSQLステートメントの複雑さを増やさないようにすると便利ですか(例:merge*applymaplydlplyなど)Rで。

一方では、SQLの結合は、各テーブルのすべての内容を選択し、R merge関数を使用してそれらを結合するよりも簡単です。また、SQLで条件付き選択を実行すると、Rにインポートする必要のあるデータの量が減ります。しかし、速度の違いは重要ではありません。

一方、複雑なwhere句を使用した大きな結合は、R構文よりも理解しにくくなります。

以下にいくつかの未テストコードを説明するためにあります:私はコードを動作させる前にこの質問をしています、そして私の質問への答えは動作するコードを必要としません(これは常に感謝されますが)-" 「最もエレガントなアプローチ」、「最少のライン」、または「Xの驚くべき実装」は常に評価されますが、私が特に興味を持っているのは、「最も賢明な/実用的な/標準的な/第一原理に基づく」理論的根拠です。

SQL where句を使用する必要があるステップと、Rを使用して実行するのが簡単なステップの一般的な答えに興味があります。

図:

データベースの説明

aab、およびbの3つのテーブルがあります。テーブルabには、それぞれ主キーidがあります。それらには、ルックアップテーブルabで表される多くの関係があります。このテーブルには、ab.a_idab.b_idに結合するフィールドa.idb.idが含まれています。 、それぞれ。どちらのテーブルにもtimeフィールドがあり、aにはgroupフィールドがあります。

ゴール:

これが私がやりたい結合とサブセット化の最小限の例です。

(MySQLの要素名、例:a.idはRのa$idと同等)

  1. aを使用して、テーブルbabを結合し、各b.timeに関連付けられたa.idの複数の値を新しい列として追加します。

    select a_time, b.time, a.id, b.id from 
           a join ab on a.id = ab.a_id 
           join b on b.id = ab.b_id and then append b.time for distinct values of b.id;
    
  2. B.timeの繰り返し値は必要ありません、必要なのはb.maxの値だけです。各b.timeに結合されたa.idの繰り返し値の場合、b.maxは値ですb.timeに最も近いがa.time以下の

    b.max <- max(b.time[b.time < a.time))
    
  3. dt <- a.time - b.maxをテーブルに追加します(例:R、
  4. a.groupの個別の値ごとに、which(min(x.dt)))を選択します。

    x.dt <- a.time - b.max
    
28
David LeBauer

私は通常、必要なデータが1つのテーブルに収まるまで、SQLでデータ操作を行い、その後、残りをRで行います。パフォーマンスの問題がある場合にのみ、計算の一部をデータベースに移動し始めます。これはすでにあなたがしていることです。

タイムスタンプを含む計算は、SQLでは読み取れなくなることがよくあります( " 分析関数 "、ddplyと同様に、これを単純化することになっていますが、MySQLでは使用できないと思います)。

ただし、例はおそらく次のように完全にSQLで記述できます(テストされていません)。

-- Join the tables and compute the maximum
CREATE VIEW t1 AS
SELECT a.id    AS a_id, 
       a.group AS a_group,
       b.id    AS b_id,
       a.time  AS a_time, 
       a.time - MAX(b.time) AS dt
FROM   a, b, ab
WHERE  a.id = ab.a_id AND b.id = ab.b_id
AND    b.time < a.time
GROUP  BY a.id, a.group, b.id;

-- Extract the desired rows
CREATE VIEW t2 AS 
SELECT t1.*
FROM t1, (SELECT group, MIN(dt) AS min_dt FROM t1) X
WHERE t1.a_id = X.a_id 
AND   t1.b_id = X.b_id 
AND   t1.a_group = X.a.group;
15

両方 SQLとR— sqldf パッケージを使用するR内ではどうでしょうか。これら は、Rデータフレームで、または既存のデータベースへの接続を介して、sqldf関数を使用する方法を示しています。そうすれば、イディオムが適切だと思われるときに、どちらでも柔軟に実行できます。

12
Alex Reynolds