这个问题与one有关。
我需要一个参数化函数来实现以下代码:
dt <- data.table( text = c("AAA 123 BBB", "1 CCC")
, text2 = c("AAA 123 BBB", "1 CCC"))
double_number <- function(x) x*2
regex_identify_num <- "\\d+"
dt[, calc_value := text |> str_extract(regex_identify_num) |> as.numeric ()|> double_number()]
dt[, text := mapply(function(x,y) gsub(regex_identify_num, x, y, perl = T), calc_value, text)]
dt[, calc_value:=NULL]
预期的结果是在所选列中获得加倍的数字,如上面的代码所示。
我试过:
change_value <- function(dt_, fun, regex, column_name) {
#browser()
dt_[, new_column := get(column_name) |> str_extract(get(regex)) |> fun()]
dt_[, column_name := mapply(function(x, y) gsub(get(regex), x, y, perl = T), new_column, get(column_name))]
dt_[, new_column := NULL]
return(dt)
}
change_value(dt, function(x) x |> as.numeric ()|> double_number(), "regex_identify_num", "text")
有趣的是,在调试时,get(column_name) |> str_extract(get(regex)) |> fun()
的评估似乎是正确的(246 2)。
我该怎么解决这个问题?
PS〉我也尝试了不同的方法(通过data.table编程),没有成功:
change_value <- function(dt_, fun, regex, column_name) {
#browser()
dt_[, new_column:= column_name|> str_extract(regex) |> fun()
, env = list( fun = substitute(fun)
, column_name = substitute(column_name)
, regex = substitute(regex)
)
]
dt_[, column_name := mapply(function(x, y) gsub(regex, x, y, perl = T), new_column, column_name)]
dt_[, new_column := NULL]
return(dt)
}
2条答案
按热度按时间r8uurelv1#
错误不发生在第一遍,只发生在第二遍(和随后的),
部分原因是,由于
data.table
的引用语义,您的dt
被修改了 * 就地 *。也许这是设计好的。但是当您这样做时,非标准求值的行为有点不同:虽然get(column_name)
位于data.table
命名空间中,但column_name
既作为函数 * 中的向量存在,又作为框架中的列存在,即上面的第三列。我们可以通过使用
data.table
的..varname
语义来解决这个问题。(重复运行不会出错)。
另一种选择是将参数和新列命名为不同的名称。
Factoid:
..
-referencing在data.table::[
的j=
部分工作,但在i=
中不工作。gg0vcinb2#
基于r2evans的观察,关键点是在将结果返回给column_name时,将column_name括在parentesis中:
通过这样做,我们避免了名称冲突,并且可以跳过
..
。然后完整的代码变为: