许多讨论R的非标准评价,功能例如with
,subset
和transform
含有这样的警告:
对于交互式使用,这是非常有效且易于阅读的。然而,对于编程,即在一个函数中,需要更加小心,通常应该避免使用
with()
,因为例如,数据中的变量可能会意外覆盖局部变量,请参阅参考资料。
(引用自 的文档with
,其他内容的信息量较少)
“参考”是这篇 2003 年的文章。坦率地说,我没有看到它的相关性。它在第 6 节中提到了关于“数据中的变量可能会意外覆盖局部变量”这一点,但它只是这样做 - 提及它。据我所知,该文章中没有任何内容告诉您警告告诉您检查参考资料尚未告诉您的任何内容。
我已经搜索了 R 手册,甚至在 3500 页的参考索引中搜索了术语“非标准”,但除了我已经提到的内容之外,我什么也没想到。我真的认为它会在语言定义中,但我已经阅读了整篇文章并没有找到它。我得到的最接近的是涵盖substitute
function的部分,我碰巧知道许多具有非标准评估的函数都依赖于此。
至于我确信找不到帮助的任何其他地方,我已经从头到尾阅读了 R 常见问题解答和R 简介。将R常见问题提到eval
和substitute
时代屈指可数,但不以任何方式与此有关。唯一值得注意的部分是here,它也建议检查 的文档deriv
,但我发现那里没有任何用处。
那么,R 是否有任何官方部分实际上记录了非标准评估的危险?我觉得很奇怪,R 的部分文档会告诉我要小心处理某些事情,而没有提供任何告诉我如何去做的地方。不可否认,需要照顾。例如,高级 R 显示了具有非标准评估的函数可能导致问题的几种方式。我之前已经为这种粗心付出了代价,不难找到带有关于非标准评估警告的评论的优秀答案。
给定 n=2,我想要一组值 (1, 1)、(1, 2) 和 (2, 2)。对于 n=3,我想要 (1, 1)、(1, 2)、(1, 3)、(2, 2)、(2, 3) 和 (3, 3)。对于 n=4、5 等,依此类推。
我想完全在基础库中完成此操作。最近,我开始使用
gen <- function(n)
{
x <- seq_len(n)
cbind(combn(x, 2), rbind(x, x))
}
Run Code Online (Sandbox Code Playgroud)
这给出了一些可行但很hacky的输出。当 n=4 时,我们得到以下结果。
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
x 1 1 1 2 2 3 1 2 3 4
x 2 3 4 3 4 4 1 2 3 4
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?在 、 、 和 R 的许多其他生成向量的方法之间expand.grid
,outer
我combn …
对于二变量问题,outer
最有可能是最好的解决方案,如果循环空间足够小,那么我们可以expand.grid
做我们的跑腿工作。然而,如果我们有两个以上的变量和一个大的空间来循环,这些就被排除了。outer
不能处理两个以上的变量,并且expand.grid
占用的内存比我见过的机器能够占用的内存多。
我最近发现自己在写这样的代码:
n<-1000
for(c in 1:n){
for(b in 1:c){
for(a in 1:b){
if(foo(a,b,c))
{
bar(a,b,c)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,嵌套循环似乎是自然的解决方案(例如,mapply
不会这样做并且没有好的因素tapply
可供使用),但是有更好的方法吗?这似乎是通往错误代码的道路。
我怀疑这combn
可能会以某种方式做到这一点,但根据我的经验,它很快就会陷入与expand.grid
. 如果没记错的话,我也知道它采取了不明智的步骤,告诉我更改递归限制的全局设置。
我搜索过,??"~"
但这只指向我rlang::env_bind
(大概是%<~%
)和base::~
. 在 RStudio 中,如何找到 Purrr 的~
文档?例如,如果我忘记了如何使用~
两个输入,我应该在哪里查看?
Tidyverse 的粉丝经常给出使用小标题而不是数据框的几个优点。它们中的大多数似乎旨在保护用户免于犯错误。例如,与数据框不同,小标题:
,drop=FALSE
参数来不从数据中删除维度。$
操作员对列名进行部分匹配。我逐渐相信用小标题替换我所有的数据框。这样做的主要缺点是什么?更具体地说,数据框可以做什么而 tibble 不能?
先发制人,我想明确表示,我不是在询问data.table
或对 Tidyverse 提出任何大局反对意见。我严格询问小标题和数据框。
[
并且[[
在使用 R 时出现很多。假设我正在讨论这两个函数,我实际上将这些“索引运算符”称为什么?我知道如何将它们命名为标点符号,但是 R 或其文档中是否有任何内容为它们提供了更具体的名称?我知道它们是在 下记录的子集函数?Extract
,但我从未见过有人称它们为“提取和双重提取”之类的东西。
Python 的 Itertools 有所谓的starmap
. 给定一个集合和一个函数,它将函数严格应用于集合内部的每个集合,并使用所述内部集合的元素作为函数的参数。例如,
from itertools import starmap\n\xc2\xa0\nNestedList = [(1, 2), (3, 4), (5, 6), (0, 0), (1, 1), (2, 2)]\n\nlist(starmap(lambda x, y:x + y, NestedList))\n
Run Code Online (Sandbox Code Playgroud)\n返回包含 3、7、11、0、2 和 4 的列表。
\n我不相信 Python 是第一个提出这个概念的人,但当我试图思考它在旧语言中的名称时,我却一片空白。Common Lisp 中是否存在类似的功能?我确信确实如此,但我无法命名。
\n我似乎无法理解Advanced R 中的以下示例。
x <- data.frame(matrix(runif(5 * 1e4), ncol = 5))
medians <- vapply(x, median, numeric(1))
y <- as.list(x)
cat(tracemem(y), "\n")
#> <0x7f80c5c3de20>
for (i in 1:5) {
y[[i]] <- y[[i]] - medians[[i]]
}
#> tracemem[0x7f80c5c3de20 -> 0x7f80c48de210]:
Run Code Online (Sandbox Code Playgroud)
我不明白为什么在这种情况下会创建一个副本,因为“如果一个对象绑定了一个名称,R 将就地修改它”,而引用的对象y
确实只y
绑定了一个名称。
r ×8
dataframe ×2
c# ×1
combinations ×1
common-lisp ×1
field ×1
for-loop ×1
interface ×1
lambda ×1
list ×1
memory ×1
nested-loops ×1
nse ×1
preview ×1
purrr ×1
python ×1
r-markdown ×1
rstudio ×1
starmap ×1
static ×1
subset ×1
terminology ×1
tibble ×1