R:它走了多远?(加上发泄)

and*_*ewH 2 evaluation scope functional-programming symbols r

我有一个名为的对象defaultPacks,包含我使用的所有计算机上安装的软件包的名称.很多缩写:

defaultPacks <- c(
  "AER",
  "plyr",
  "dplyr" 
) 
Run Code Online (Sandbox Code Playgroud)

我想将此对象保存到共享目录中的文件,所有这些目录都可以到达.我正在使用Dropbox,当R运行时,同步始终暂停.

save(defaultPacks, 
file.path("C:","Users","andrewH","Dropbox","R_PROJ","sharedSettings.rdata")) 
Run Code Online (Sandbox Code Playgroud)

然后我想加载对象并安装其名称在对象中的包defaultPacks.

SyncPacks <- function(fileString){
  defaultPacks <- load(file=fileString)
  install.packages(defaultPacks, repos="http://cran.us.r-project.org")
}
SyncPacks(file.path("C:","Users","andrewH","Dropbox","R_PROJ","sharedSettings.rdata")
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我会收到警告:

Warning in install.packages: package ‘defaultPacks’ is not available (for R version 3.2.1)
Run Code Online (Sandbox Code Playgroud)

defaultPacks加载并分配后立即查看内容:字符串"defaultPacks".所以它似乎只是一个字符串而不是一个对象.

所以我回到我的保存,然后尝试

save(get(defaultPacks), file.path(etc.))
Run Code Online (Sandbox Code Playgroud)

这给了我一个不同的错误:

Error in save(get("defaultPacks"), file = file.path("C:", "Users", "andrewH",  : 
  object ‘get("defaultPacks")’ not found.
Run Code Online (Sandbox Code Playgroud)

然后我试着dynGet()用同样的结果.

因此,在将符号视为字符串之前,现在它将函数视为字符串.

所以我尝试使用list选项进行保存:

save(list = defaultPacks, file = file.path(etc))
Run Code Online (Sandbox Code Playgroud)

并得到另一个错误:

Error in save(list = defaultPacks, file = file.path("C:", "Users", "andrewH",  : 
  objects ‘AER’, ‘plyr’, ‘dplyr’, (etc.) not found
Run Code Online (Sandbox Code Playgroud)

那么,之前我不能让我的特征向量,现在我拍右过去吧,估计defaultPacks找字符串,然后把每个字符串作为一个象征,评估其(不存在)对象.

所以,我想知道如何使这项工作.但我要的不仅仅是这个.我一直有这个问题,或类似的问题.使用R几年后,我仍然每周都有几次.我不知道R会在任何特定场合采取多少步骤.我将函数作为对象名称,函数将其视为字符串.我将一个函数交给一个字符串,然后R函数将它转换为符号并尝试对其进行求值.在这里,我不明白为什么save函数不保存我给它的对象,然后再给它load.

我已经阅读了关于在十本不同的R书中进行范围界定的讨论,从钱伯斯的"数据分析软件"到威克汉姆的"高级R".两次.在某些情况下有四次.我知道函数的四个环境,以及调用堆栈和环境父项链之间的区别.然而,很明显我遗漏了一些基本的东西.这不仅仅是因为我不知道为什么save不在其...参数中取名并将其保存为对象(除非问题出在加载端).我不知道我怎么知道.函数描述在...s中表示"要保存的对象的名称(作为符号或字符串)".那么为什么将名称保存为字符串呢?或者为什么加载返回一个字符串,如果保存保存一个对象?我怎么能预测呢?

经验丰富的R程序员,我知道你可以提前告诉给定的R函数如何处理它的一个参数.你知道它的评估范围.您可以根据需要进行操作,然后停止.str()每当你想弄清楚它认为它的论点意味着什么时,你就不必在你的函数中写入.你怎么做呢?

血腥的"R Inferno".这是轻描淡写的.

Mar*_*gan 6

查看问题的一种方法是注意defaultPacks从这些操作之前到之后的更改值.

> fname = tempfile()
> orig = defaultPacks = c("AER", "plyr", "dplyr")
> save(defaultPacks, file=fname)
> defaultPacks = load(fname)
> identical(orig, defaultPacks)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

问题始于对什么save()做的理解.从中?save,保存的对象被命名defaultPacks并且具有值c("AER", "plyr", "dplyr").save()可以保存多个对象,每个对象都有一个名称和相关的值,因此它必须以某种方式保存每个对象的名称.

load()恢复save()已写入的对象,并返回(从?load)"创建的对象名称的字符向量".在这种情况下,load()恢复(在全局环境中创建)符号defaultPacks,使用默认包的字符向量填充它,并返回已恢复的对象的名称(即长度为1"defaultPacks"的字符向量).然后返回值将覆盖恢复的值,我们有defaultPacks = "defaultPacks".

install.packages它没有做任何与它的第一个参数有关的东西,它来自?install.packages"应该下载当前版本的包名称的字符向量".字符向量恰好是符号defaultPacks,但错误来自符号的值,即符号"defaultPacks".

save()并且load()或多或少都有工作他们做支持多个对象的方式.在另一方面saveRDS()readRDS()(好吧,为什么,而不是负担?)有合同保存单个对象.无需存储已保存对象的名称即可恢复与其关联的值.因此saveRDS(defaultPacks, fname); defaultPacks = readRDS(fname)工作,尤其是defaultPacks这一系列操作之前和之后的价值保持不变.

> orig = defaultPacks = c("AER", "plyr", "dplyr")
> saveRDS(defaultPacks, fname)
> defaultPacks = readRDS(fname)
> identical(orig, defaultPacks)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

没有太多的混蛋,回答"经验丰富的R程序员......你怎么做?" ?通过仔细阅读手册,上述内容暗示了答案.此外,基础R代码中没有很多地方评估是非标准的 - 公式并且library是主要的罪魁祸首 - 所以认识到问题不是可以帮助关注实际发生的事情.