我正在尝试扩展data.table
以加快/标准化复杂调查设计的分析。为此,我尝试[.data.table
在拦截呼叫的位置上添加一个浅层,j
并在某些情况下在需要特殊测量类型命令时替换操作(例如mean
to median
)(或在特殊命令类型时使用常规功能)无需利用data.table
的geforce类型优化)。
基于我对s3调度的部分理解,NextMethod
应该是这里合适的功能,但是它似乎正在j
作为符号传递j
(例如,a[, j]
代替a[, median(v1)]
它与data.table的NSE进行了怪异的交互。我已经尝试了使用do.call的版本,但是不会经过一些无限递归的废话(do.call('[', ...)
将无休止地调度[.dtsurvey
)
有没有一种干净的方法来调整参数并将其传递给data.table
?在下面的玩具示例中,即使初始操作为,我也希望调用返回median
column的v1
值mean
。
library('data.table')
a = data.table(v1 = 1:10)
b = copy(a)
"[.dtsurvey" <- function(x, i, j, by, ...){
j = substitute(j)
print(j)
if(j[[1]] == 'mean') j[[1]] = quote(median)
print(j)
NextMethod(`[`, x)
}
class(a) <- c('dtsurvey', class(a))
a[, mean(v1)]
#> mean(v1)
#> median(v1)
#> Error in `[.data.table`(a, , mean(v1)): j (the 2nd argument inside [...]) is a single symbol but column name 'j' is not found. Perhaps you intended DT[, ..j]. This difference to data.frame is deliberate and explained in FAQ 1.1.
由reprex软件包(v0.3.0)创建于2020-10-08
我认为您无法在此处利用NextMethod,据我所知,它在传递参数时会考虑这些参数。这是一种方法:
library(data.table)
a = data.table(v1 = c(1,2,9))
b = copy(a)
"[.dtsurvey" <- function(x, i, j, by, ...){
mc <- match.call()
j <- substitute(j)
j <- do.call(substitute, list(j, list(mean = quote(median))))
mc[["j"]] <- j
mc[[1]] <- quote(data.table:::`[.data.table`)
eval.parent(mc)
}
class(a) <- c('dtsurvey', class(a))
a[, mean(v1)]
#> [1] 2
b[, mean(v1)]
#> [1] 4
由reprex软件包(v0.3.0)创建于2020-10-08
或者:
"[.dtsurvey" <- function(x, i, j, by, ...){
mc <- match.call()
mc[["j"]] <- do.call(substitute, list(substitute(j), list(mean = quote(median))))
mc[[1]] <- quote(`[`)
mc[[2]] <- substitute(as.data.table(x))
eval.parent(mc)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句