R代码
mysql> DROP TABLE IF EXISTS `slow_log`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `slow_log` (
-> `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
-> ON UPDATE CURRENT_TIMESTAMP(6),
-> `user_host` mediumtext NOT NULL,
-> `query_time` time(6) NOT NULL,
-> `lock_time` time(6) NOT NULL,
-> `rows_sent` int NOT NULL,
-> `rows_examined` int NOT NULL,
-> `db` varchar(512) NOT NULL,
-> `last_insert_id` int NOT NULL,
-> `insert_id` int NOT NULL,
-> `server_id` int unsigned NOT NULL,
-> `sql_text` mediumtext NOT NULL
-> ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log';
Query OK, 0 rows affected (0.00 sec)
我明白了:
library(data.table)
x <- 4
f1 <- function(){
x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==get("x", envir=parent.env(environment()))]
}
f1()
f2是一个删除函数中 x y
1: 1 1
2: 1 5
3: 1 9
的新函数。
x <- 1
我明白了:
f2 <- function(){
#x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==get("x", envir=parent.env(environment()))]
}
f2()
那是对的,我的问题是如何编写一个函数来替换x y
1: 4 4
2: 4 8
3: 4 12
?
谢谢!
答案 0 :(得分:1)
我只是意识到OP正在从函数的封闭环境中抓取x
,而不是将其作为参数传递。我认为这是一种不好的做法,并没有真正对此案例提出建议。我可能会删除这个答案(只包括将x
传递给函数),如果它太过分散注意力。
library(data.table)
dt <- data.table(x=1:4,y=1:12)
ff = function(x, ...){
mDT = data.table(x)
dt[mDT, on=.(x), ...]
}
ff(4L, verbose = TRUE)
# Calculated ad hoc index in 0 secs
# Starting bmerge ...done in 0 secs
# x y
# 1: 4 4
# 2: 4 8
# 3: 4 12
这仅解决了OP DT[x == get("x", ...)]
的具体示例,而不是更广泛的表达。对于那些,构建和评估表达式应该有效:
fs = function(x, ...){
e = substitute(x == ..x, list(..x = x))
dt[eval(e), ...]
}
fs(4L, verbose = TRUE)
# Creating new index 'x'
# Starting bmerge ...done in 0 secs
# x y
# 1: 4 4
# 2: 4 8
# 3: 4 12
fs(3L, verbose = TRUE)
# Using existing index 'x'
# Starting bmerge ...done in 0 secs
# x y
# 1: 3 3
# 2: 3 7
# 3: 3 11
详细输出表明fs
创建索引,这有助于提高速度。请参阅vignette("datatable-secondary-indices-and-auto-indexing")
。
Eventually,可能有语法,所以我们可以简单地写...
dt[..x == x]
可能使用链接中提出的inherits = TRUE
参数来确保安全性(因此x
必须是一列,并且(i)x
必须存在于父环境中或{{1必须是列名。)
答案 1 :(得分:1)
@Frank,谢谢!根据这篇文章variable usage in data.table,我写了一个函数:
`..` <- function(x){
stopifnot(inherits(x, "character"))
stopifnot(length(x)==1)
get(x, parent.frame(4))
}
x <- 4
f1 <- function(){
x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==..("x")]
}
f1()
f2 <- function(){
#x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==..("x")]
}
f2()
f1和f2都得到了正确的结果!
为什么是parent.frame(4)?
我们首先看到代码:
current_frame <- sys.nframe()
dt <- data.table()
dt[, sys.nframe() - current_frame]
我们得到4,这应该是原因。
答案 2 :(得分:0)
我发现旧解决方案不适用于data.table 1.11.4,我写了一个新解决方案:
.. <- function (x, env = parent.frame())
{
stopifnot(inherits(x, "character"))
stopifnot(length(x) == 1)
get(x, envir = parent.env(env))
}
x <- 4
f1 <- function(){
x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==..("x")]
}
f1j <- function(){
x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[, ..("x")]
}
f2 <- function(){
#x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[x==..("x")]
}
f2j <- function(){
#x <- 1
dt <- data.table(x=1:4,y=1:12)
dt[,..("x")]
}
stopifnot(all(f1()$y==c(1,5,9)))
stopifnot(all(f1j()==c(1)))
stopifnot(all(f2()$y==c(4,8,12)))
stopifnot(all(f2j()==c(4)))
我已经测试了它适用于data.table_1.10.4-3和data.table_1.11.4。
实际上,我对R的parent.frame和如何在R中找到正确的变量感到困惑,我只是测试了一些可能的方法,直到获得预期的结果。