我有一个包含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
列,然后以某种方式将结果强制转换为向量然后分配到新的name_final
列。但是,我期望的行为将是逐行的。我可以通过添加虚拟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而不是行的原子列有关,但我想了解那里发生了什么。
答案 0 :(得分:3)
R中几乎没有任何东西在逐行的基础上运行。一次使用数据列总是更好,因此您可以假设整个列值向量将作为参数传递给您的函数。这是一种为regmatches列表中的每个项目提取第二个元素的方法
dt[, name_final := sapply(regmatches(name, regexec(pattern, name)), `[`, 2)]
sapply()
或Vectorize()
等功能可以&#34;假&#34;对于不能一次在矢量/数据列表上运行的函数的每行类型调用。