29

我有一个中等大小的数据库,其中包含许多连接和查找表。

我对 R 比对 SQL 更熟悉,而且我使用的是 MySQL。

我的问题:

在什么时候停止增加 SQL 语句的复杂性以支持 R 中的数据子集功能(例如,、、、、merge等)在 R*apply中是有益的。maplydlply

一方面,SQL 的连接比选择每个表的所有内容并使用 Rmerge函数连接它们更容易。此外,在 SQL 中进行条件选择会减少必须导入 R 的数据量;但速度差异并不显着。

另一方面,与 R 语法相比,带有复杂 where 子句的大连接变得不那么容易理解。

下面我有一些未经测试的代码用于说明目的:我在有工作代码之前问这个问题,我的问题的答案不需要工作代码(尽管这总是值得赞赏的) - “最优雅的方法”,“最少行”或“X 的惊人实现”总是受到赞赏,但我特别感兴趣的是“最明智/实用/规范/基于第一原则”的基本原理。

我对哪些步骤应该使用 SQLwhere子句以及哪些步骤使用 R 更容易完成的一般答案感兴趣。

插图:

数据库描述

共有三个表:aabba并且每个表b都有一个主键id。它们具有由查找表 表示的多对多关系,该表ab包含字段ab.a_id并分别ab.b_id连接到a.id和。b.id两个表都有一个time字段,a 有一个group字段。

目标:

这是我想做的连接和子集的最小示例;

(MySQL对元素的命名,例如a.id相当于a$idR中的)

  1. 连接表ab使用,将与每个关联的ab多个值附加为新列;b.timea.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加入 each的重复值a.idb.maxb.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
    
4

2 回答 2

15

我通常在 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;
于 2012-03-20T23:40:10.417 回答
13

为什么不同时使用SQL 和 R——在 R 中使用sqldf包?这些 示例展示了如何sqldf通过 R 数据框或通过与现有数据库的连接来使用该函数。这样,您就可以灵活地按照习语认为合适的方式进行操作。

于 2012-03-20T21:16:41.500 回答