bsk*_*ggs 1 wolfram-mathematica r list-manipulation
Mathematica有一种有趣的方法,可以逐步构建一个列表(或多个列表),您可以在复杂计算的各个点计算结果.我想在R里做类似的事情.
在Mathematica中,您可以Sow通过在调用函数时包装整个计算来收集计算期间每个函数调用的每个参数的列表Reap.R是否具有这些功能的等价物?您是否可以使用环境和<<-运营商来模拟它,或者范围规则是否允许它?
编辑:这是一个人为的例子.假设我想生成一个多维数据集的总和,但我还想收集我用来制作多维数据集总和的数字的平方.我知道可能有更多惯用的方法来进行这种精确计算,但它代表了在收集沿途生产的各种物品时获得最终答案.
reap(sum(sapply(1:100, function(i) { sow(squares = i * i); i * i * i }))
Run Code Online (Sandbox Code Playgroud)
我希望这能返回具有多维数据集总和以及包含正方形列表的命名变量"squares"的内容.
我没有对此进行过彻底的测试,但它似乎适用于您的简单示例.在这里我们定义reap和sow
reap <- function(...) {
expr <- substitute(...)
REAPENV <- new.env()
parent.env(REAPENV) <- parent.frame()
x <- eval(expr, REAPENV)
c(list(x), as.list(REAPENV))
}
sow <- function(...) {
expr <- substitute(alist(...))[-1]
for( f in rev(sys.frames())) {
if(exists("REAPENV", envir=f)) {
re <- get("REAPENV", envir=f)
if (is.null(names(expr))) {
names(expr) <- if(length(expr)==1) {"sow"} else {letters[1:length(expr)]}
}
stopifnot(all(nchar(names(expr))!=0))
for(n in names(expr)) {
sx <- eval(expr[[n]], parent.frame())
cv <- if(exists(n, envir=re, inherits=FALSE)) {get(n, envir=re)} else {list()}
if(length(cv)>0) {
assign(n, append(cv, sx), envir=re)
} else {
assign(n, sx, envir=re)
}
}
break;
}
}
invisible(NULL)
}
Run Code Online (Sandbox Code Playgroud)
因此,该reap()函数基本上只定义了一个新环境,并在该上下文中调用它的参数.该sow函数接受一个命名参数列表,并评估它的参数并分配到最近的封闭"reap"环境.最后,reap()将返回一个列表,其中包含作为第一个元素传递的表达式的"自然"返回值,然后它将添加与sow()调用期间使用的名称对应的命名元素.所以,如果你跑
reap(sum(sapply(1:5, function(i) { sow(squares=i * i); i * i * i; })))
Run Code Online (Sandbox Code Playgroud)
你得到
[[1]]
[1] 225
$squares
[1] 1 4 9 16 25
Run Code Online (Sandbox Code Playgroud)
正如我所提到的,这似乎适用于简单的测试用例.我确信可以改进寻找和分配正确的工作收割环境.但这可能提供一个起点,至少你是否应该追求这样的事情.