Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 为什么data.table j在直接调用mget()和在另一个函数中调用mget()时有不同的环境?_R_Data.table - Fatal编程技术网

R 为什么data.table j在直接调用mget()和在另一个函数中调用mget()时有不同的环境?

R 为什么data.table j在直接调用mget()和在另一个函数中调用mget()时有不同的环境?,r,data.table,R,Data.table,我想将mget()封装在一个简单的函数中,以便它返回一个未命名的列表,并在data.table j中使用此函数 我已经打印出传递给data.table j的函数体中的环境。我发现data.table j在调用我的函数时使用一种环境,在使用unname(mget())时使用另一种环境。我尝试过使用inherits,但是在这里使用了inherits=F来更严格地说明我们在哪里可以找到相关变量 这种方法在以下方面起作用: 库(data.table);图书馆(purrr) #用户可以访问的功能列表 fu

我想将
mget()
封装在一个简单的函数中,以便它返回一个未命名的列表,并在data.table j中使用此函数

我已经打印出传递给data.table j的函数体中的环境。我发现data.table j在调用我的函数时使用一种环境,在使用
unname(mget())
时使用另一种环境。我尝试过使用inherits,但是在这里使用了
inherits=F
来更严格地说明我们在哪里可以找到相关变量

这种方法在以下方面起作用:

库(data.table);图书馆(purrr)
#用户可以访问的功能列表
functionDictionary这里有一种方法:

ff = function(d, g, uL, dict = functionDictionary){
  r    = uL$reactive
  nms  = r$names
  fns  = names(r$calculations)
  cols = r$calculations

  exprs = lapply(setNames(seq_along(nms), nms), function(ii){
    fx = substitute(dict[[f]], list(f=fns[[ii]]))
    cx = lapply(cols[[ii]], as.name)
    as.call(c(fx, cx))
  })
  cat("The expressions:\n"); print(exprs)

  call = as.call(c(as.name("list"), exprs))
  cat("The call:\n"); print(call)

  d[, eval(call), by=g]
} 
用法:

ff(mtcars, grouping_vars, userList)

The expressions:
$my_var1
dict[["sum"]](hp)

$my_var2
dict[["weighted_sum"]](hp, mpg)

The call:
list(my_var1 = dict[["sum"]](hp), my_var2 = dict[["weighted_sum"]](hp, 
    mpg))
   cyl vs my_var1   my_var2
1:   6  0     395  6.401945
2:   4  1     818  3.060232
3:   6  1     461  6.026144
4:   8  0    2929 13.855251
5:   4  0      91  3.500000
评论。purrr的map2函数除了数据之外还有自己的NSE(如OP中所示的
~
.x
.y
),表的NSE因此即使您找到了解决特定情况的方法(如OP中提到的
eval(as.symbol(z))
在这里工作),事情也可能变得混乱

我发现基本的R工具(如quote和substitute)可以推广到我的更多用例中;而
eval
是使用data.table进行元编程的标准方法,并允许使用其各种优化。如果这些优化对您的用例很重要,那么您可能需要考虑更改functionDictionary接口,因为使用
verbose=TRUE
我们可以看到,只有下面的第二个调用得到“GForce”优化:

mtcars[, functionDictionary[["sum"]](hp), by=cyl, verbose=TRUE]
# ...
# lapply optimization is on, j unchanged as 'functionDictionary[["sum"]](hp)'
# GForce is on, left j unchanged
# ...
mtcars[, sum(hp), by=cyl, verbose=TRUE]
# ...
# lapply optimization is on, j unchanged as 'sum(hp)'
# GForce optimized j to 'gsum(hp)'
# ...

我的假设是,因为我不熟悉
data.table
的内部结构:如果
data.table
可以明确地“看到”代码中使用了
mget
,它将公开表中的所有变量。您的
mget\u unnamed
函数“隐藏”
mget
,因此
data.table
仅根据它看到的内容公开它认为代码仍在使用的内容。其他R函数的工作原理与此类似。我没有看到对“data.table”包的库调用。另外,
map2
来自非基本包,因此该调用在干净会话中抛出错误。@42谢谢。我已将库调用添加到代码中的那些包中。@Alexis您是对的。在传递到上面data.table j的函数体中使用get将取消显示“hp”。e、 g.{env@Frank看起来你在这里使用了replacement而不是get():。我想你也会做类似的事情吗?看起来~do.call(functionDictionary[.x]]、lapply(.y,function(z)eval(as.symbol(z)))在这里也可以工作,而不需要声明环境。有任何反对使用eval的建议吗(as.symbol())与quote/substitute相反?谢谢!我从这篇文章中学到了很多。一旦我的编辑获得批准,我会接受你的答案。quote/substitute最好的部分似乎是,你可以生成与“典型的”
data.table
语法非常相似的调用。我的用例是模板化闪亮的应用程序生产,因此优化是一个值得关注的问题,因此该注释也很有用。