【问题标题】:data.table assignment operator with lists in Rdata.table 赋值运算符与 R 中的列表
【发布时间】:2015-01-22 16:05:00
【问题描述】:

我有一个包含 name 列的 data.table,我正在尝试从该名称中提取正则表达式。在这种情况下,最明显的方法是使用:= 运算符,因为我将这个提取的字符串指定为数据的实际名称。在这样做时,我发现这实际上并没有以我期望的方式应用该功能。我不确定这是否是故意的,我想知道它这样做是否有原因,或者它是否是一个错误。

library(data.table)
dt <- data.table(name = c('foo123', 'bar234'))

在简单字符向量中搜索所需表达式的行为符合预期:

name <- dt[1, name]
pattern <- '(.*?)\\d+'
regmatches(name, regexec(pattern, name))
[[1]]
[1] "foo123" "foo"  

我可以轻松地对其进行子集化以获得我想要的东西

regmatches(name, regexec(pattern, name))[[1]][2]
[1] "foo"

但是,当我尝试将其应用于整个 data.table 时遇到了问题:

dt[, name_final := regmatches(name, regexec(pattern, name))[[1]][2]]
dt
    name name_final
1: foo123        foo
2: bar234        foo

我不知道 data.table 内部是如何工作的,但我猜该函数首先应用于整个name 列,然后以某种方式将结果强制转换为向量,然后分配给新的@ 987654328@专栏。但是,我在这里期望的行为将是逐行的。我可以通过添加一个虚拟的id 列来模拟这种行为;

dt[, id := seq_along(name)]
dt[, name_final := regmatches(name, regexec(pattern, name))[[1]][2], by = list(id)]
dt
    name name_final id
1: foo123        foo  1
2: bar234        bar  2

这不是默认行为是否有原因?如果是这样,我猜它与列对 data.table 的原子性而不是行有关,但我想了解那里发生了什么。

【问题讨论】:

  • 如果它真的这么简单,那么是的,我可以。我正在寻找的实际表达式更复杂,但我认为一个简单的例子会更好地说明这个问题。
  • 为了澄清,我试图提取一个与更复杂的正则表达式匹配的捕获组,而不是简单地“获取所有字符直到数字”。捕获组使 regexec 成为必要(我认为),而正则表达式本身使仅使用 gsub 变得更加困难。
  • @RichardScriven 你所说的行是有道理的,但我不确定 data.table 是否将整个列作为参数传递给函数或实际逐行操作时使用:= 运算符。提供的答案似乎回答了这个问题
  • 我指的是您声称该函数没有逐行运行。 name &lt;- dt[1, name] 部分不正确,但也不相关,因为无论如何这不是我在示例中操作的内容
  • @RichardScriven 关于regexec 返回值,但是,这直接来自文档:“regexec 返回与文本长度相同的列表”

标签: r data.table


【解决方案1】:

R 中几乎没有什么是逐行运行的。一次处理数据列总是更好,因此您几乎可以假设整个列向量值将作为参数传递给您的函数。这是一种为 regmatches 列表中的每个项目提取第二个元素的方法

dt[, name_final := sapply(regmatches(name, regexec(pattern, name)), `[`, 2)]

sapply()Vectorize() 之类的函数可以“伪造”对不打算一次在向量/数据列表上运行的函数的每行类型调用。

【讨论】:

  • 所以这行得通,因为它基本上作用于结果列表的每个元素并只获取第二个元素,将结果转换为可以轻松绑定到表格的向量作为新列?跨度>
  • 对。这个想法是,如果你将一个向量传递给一个函数,你应该得到一个长度相同的向量。所以我们假设name 值将作为向量传入,并且只是想确保我们的表达式返回一个向量(每个元素一个结果)。这在很大程度上是设计使然,几乎所有的基本函数都被“矢量化”以适应这种行为。这就是让 R 能够很好地工作的原因。
猜你喜欢
  • 2019-07-01
  • 2014-05-27
  • 2020-11-16
  • 2014-03-23
  • 2017-11-21
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
  • 2014-06-12
相关资源
最近更新 更多