【问题标题】:When to use R, when to use SQL?什么时候用R,什么时候用SQL?
【发布时间】:2012-04-05 09:46:08
【问题描述】:

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

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

我的问题:

在什么情况下停止增加 SQL 语句的复杂性以支持 R 中的数据子集功能(例如,merge*applymaplydlply 等)在R.

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

另一方面,带有复杂 where 子句的大连接变得比 R 语法更难理解。

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

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

插图:

数据库说明

共有三个表:aabb。表ab 都有一个主键id。它们具有由查找表ab 表示的多对多关系,其中包含分别连接到a.idb.id 的字段ab.a_idab.b_id。两个表都有一个time 字段,a 有一个group 字段。

目标:

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

(MySQL对元素的命名,例如a.id等价于R中的a$id

  1. 使用ab 连接表ab,将与每个a.id 关联的b.time 的多个值附加为新列;

    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.idb.maxb.time的值最接近到但不大于a.time

    b.max <- max(b.time[b.time < a.time))
    
  3. 将值dt &lt;- a.time - b.max附加到表中,例如,在R中,
  4. 对于a.group 中的每个不同值,选择 which(min(x.dt)))

    x.dt <- a.time - b.max
    

【问题讨论】:

  • “最接近但不大于”听起来像 roll=TRUE 加入包 data.table。该操作在 SQL 中可能非常缓慢,但在 R 中使用短语法时非常快。zooxts 和其他包中也有 locf

标签: sql r database data.table


【解决方案1】:

我通常在 SQL 中进行数据操作 直到我想要的数据在一个表中, 然后,我在 R 中完成其余的工作。 仅在出现性能问题时 我是否开始将一些计算转移到数据库中。 这已经是你正在做的事情了。

经常涉及时间戳的计算 在 SQL 中变得不可读 (“analytic functions”,类似于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;

【讨论】:

  • 准确地说,是 SQL 中的子集,并且只将您分析所需的内容带入 R。
  • 这是个好主意,但是在 MySQL 中使用视图比在 R 中使用 data.table 慢(即使 MySQL 服务器比我的桌面快得多)-我在 dba 上提出了一个相关问题.SE:dba.stackexchange.com/questions/16372/… 看来浏览速度很慢。尽管如此,速度损失大约是一分钟,如果令人讨厌,这是可以容忍的。
【解决方案2】:

为什么不用both SQL 和 R — 在 R 中使用 sqldf 包?这些examples 展示了如何将sqldf 函数与R 数据帧或通过与现有数据库的连接一起使用。这样一来,您就可以根据习惯用法灵活地做任何事情。

【讨论】:

  • 我实际上两者都用。我有一个函数 query 环绕 dbSendQuery() 函数,所以我可以,例如 query("select * from a ...)。但问题是,SQL 查询应该有多复杂,我什么时候应该将表导入 R 并执行连接、选择和基本算术(最小值、最大值、+、-、*、/ 等),在R. 我的问题是“哪些成语最适合 R 与 MySQL。
  • 似乎人们一直在上下投票。我想我会留下我的答案,以防它对其他不太了解它已经被使用的人有用,也许它会帮助他们。那,我喜欢过山车。哇!
  • +1;尽管示例中没有介绍,但 sqldf 可以直接连接到数据库;很有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-09-28
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多