【问题标题】:R: When using data.table how do I get columns of y when I do x[y]?R:当使用 data.table 时,当我执行 x[y] 时如何获得 y 列?
【发布时间】:2011-06-13 11:03:41
【问题描述】:

更新:老问题......它已在 2011 年 2 月由 data.table v1.5.3 解决。

我正在尝试使用data.table 包,并且非常喜欢我得到的加速,但是当我执行x[y, <expr>] 时,我被这个错误难住了,其中xy 是“数据表”具有相同的键,并且<expr> 包含xy 的列名:

require(data.table)
x <- data.table( foo = 1:5, a = 5:1 )
y <- data.table( foo = 1:5, boo = 10:14)
setkey(x, foo)
setkey(y, foo)
> x[y, foo*boo]
Error in eval(expr, envir, enclos) : object 'boo' not found

更新... 为了阐明我在上面的示例中寻找的功能:我需要执行以下等效操作:

with(merge(x,y), foo*boo)

但是,根据data.table FAQ 的以下摘录,这应该有效:

最后,虽然看起来好像 x[y] 不返回 y 中的列, 您实际上可以使用来自 y 在 j 表达式中。这就是我们 意思是加入继承范围。为什么不 只是返回所有的联合 来自 x 和 y 的列,然后运行 对此的表达?归结为 代码效率和更快 编程。当你写 x[y,fooboo], data.table 自动 检查 j 表达式以查看哪个 它使用的列。它只会子集, 或组,仅这些列。记忆 仅为 j 列创建 用途。假设 foo 在 x 中,而 boo 在 y 中(连同其他 20 列 在 y)。 x[y,fooboo] 不是更快吗 程序和运行速度比 合并步骤后跟另一个子集 步骤?

我知道this question 解决了类似的问题,但似乎没有得到令人满意的解决。有谁知道我错过了什么或误解了什么?谢谢。

更新:我在数据表帮助邮件列表和包作者(Matthew Dowle)replied 上询问确实上面引用的常见问题解答是错误的,所以我使用的语法目前不起作用,即我无法参考当我做x[y,...] 时,到j(即第二个)参数中的y 列。

【问题讨论】:

  • 但您前段时间问过,2011 年 2 月发布给 CRAN 的 v1.5.3 解决了这个问题。请查看它的新闻、新的 ?data.table 和更正的常见问题解答。
  • @Matthew 谢谢你,是的,我知道最新版本已经解决了这个问题,很高兴你在这里指出了这一点,以便其他人清楚。

标签: r data.table


【解决方案1】:

我不确定我是否很好地理解了这个问题,而且我也刚刚开始阅读 data.table 库的文档,但我想如果你想获得 y 并通过 a 的列对那些做一些事情,你可以尝试类似:

> x[y,a*y]
     foo boo
[1,]   5  50
[2,]   8  44
[3,]   9  36
[4,]   8  26
[5,]   5  14

在这里,您将得到 y 的列乘以 xa 列。如果你想得到xfoo乘以yboo,试试:

> y[,x*boo]
     foo  a
[1,]  10 50
[2,]  22 44
[3,]  36 36
[4,]  52 26
[5,]  70 14

编辑后:感谢@Prasad Chalasani 让我的问题更清楚。

如果首选简单合并,那么以下应该可以工作。我编了一个更复杂的数据来更深入地了解这些操作:

x <- data.table( foo = 1:5, a=20:24, zoo = 5:1 )
y <- data.table( foo = 1:5, b=30:34, boo = 10:14)
setkey(x, foo)
setkey(y, foo)

因此,每个 data.table 中只添加了一个额外的列。让我们看看merge 并用data.tables 做吧:

> system.time(merge(x,y))
   user  system elapsed 
  0.027   0.000   0.023 
> system.time(x[,list(y,x)])
   user  system elapsed 
  0.003   0.000   0.006 

后者看起来要快得多。虽然结果并不相同,但可以以相同的方式使用(后一次运行的额外列):

> merge(x,y)
     foo  a zoo  b boo
[1,]   1 20   5 30  10
[2,]   2 21   4 31  11
[3,]   3 22   3 32  12
[4,]   4 23   2 33  13
[5,]   5 24   1 34  14
> x[,list(x,y)]
     foo  a zoo foo.1  b boo
[1,]   1 20   5     1 30  10
[2,]   2 21   4     2 31  11
[3,]   3 22   3     3 32  12
[4,]   4 23   2     4 33  13
[5,]   5 24   1     5 34  14

所以要获得xy,我们可以使用:xy &lt;- x[,list(x,y)]。要从 xy$foo * xy$boo 计算单列 data.table,以下方法可能有效:

> xy[,foo*boo]
[1] 10 22 36 52 70

嗯,结果不是 data.table 而是一个向量。


更新(2012 年 3 月 29 日):感谢 @David 提醒我注意上述示例中使用了 merge.data.table

【讨论】:

  • 参考我的问题中的示例,我想做xy的连接,我们称之为xy,然后创建一个单列数据框等于xy$foo * xy$boo
  • @Prasad Chalasani:我编辑了我的答案,希望你能从中找到新的和有价值的东西。
  • 感谢您提供详细信息,但我的问题是为什么我在问题中描述的特定语法不起作用,这与常见问题解答中所说的相反。我知道我可以分两个阶段完成(合并,然后对列进行操作),但我希望x[y, &lt;expr&gt;] 语法一步​​完成 - 即进行连接并在@ 上操作987654338@ 和 y 列在一步。这在语法上不那么乏味,并且可能更快(如果在内部实现)。我正在处理 1000 万行数据帧,所以我不关心上面小玩具示例的时间安排。
  • @Prasad Chalasani:我明白了,那么我的“答案”似乎是没有答案 :( 我想常见问题解答在那部分是不正确的,正如@f3lix 所建议的那样。
  • 这已由 2011 年 2 月发布给 CRAN 的 v1.5.3 解决。请查看它的新闻、新的 ?data.table 和更正的常见问题解答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 2021-09-11
相关资源
最近更新 更多