【发布时间】: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 <- dt[1, name]部分不正确,但也不相关,因为无论如何这不是我在示例中操作的内容 -
@RichardScriven 关于
regexec返回值,但是,这直接来自文档:“regexec 返回与文本长度相同的列表”
标签: r data.table