R中的引用调用(使用函数修改对象)

R中的引用调用(使用函数修改对象),r,function,R,Function,我刚刚在R中大吃一惊,惊讶地发现函数没有修改对象,至少看起来这是默认的。例如,我编写了一个函数,只在表中的一个标签上粘贴一个星号;它在函数内部工作,但表本身没有更改。(我主要来自Ruby) 那么,使用函数来更改R中的对象的正常、可接受的方式是什么呢?如何在表格标题中添加星号 替换整个对象:myTable=title.asterisk(myTable) 使用变通方法通过引用调用(如TszKin Julian 使用函数以外的结构?对象方法 这两种范例是替换整个对象,如您所示,或者编写“替换”函数,

我刚刚在R中大吃一惊,惊讶地发现函数没有修改对象,至少看起来这是默认的。例如,我编写了一个函数,只在表中的一个标签上粘贴一个星号;它在函数内部工作,但表本身没有更改。(我主要来自Ruby)

那么,使用函数来更改R中的对象的正常、可接受的方式是什么呢?如何在表格标题中添加星号

  • 替换整个对象:
    myTable=title.asterisk(myTable)

  • 使用变通方法通过引用调用(如TszKin Julian

  • 使用函数以外的结构?对象方法


这两种范例是替换整个对象,如您所示,或者编写“替换”函数,如

`updt<-` <- function(x, ..., value) {
    ## x is the object to be manipulated, value the object to be assigned
    x$lbl <- paste0(x$lbl, value)
    x
}

但在我看来,“语法糖”这个标签并不能真正体现所涉及的中心范式。它能够方便地进行就地更新,这与R通常保持的“更改时复制”错觉不同,它实际上是更新对象的“R”方式(例如,不要使用
?referenceclass
,它更像其他语言的感觉,但会让希望在更改时复制语义的R用户感到惊讶).

您遇到问题的原因是,您正在将对象传递到函数的本地命名空间。这是R的一个伟大/可怕之处:它允许隐式变量声明,然后随着命名空间的加深而实现supercedence

这会影响您,因为函数在当前名称空间中创建了一个新名称空间。我假设对象“myTable”最初是在全局名称空间中创建的,但当它传递到函数“title.asterisk”中时,新函数本地名称空间现在有一个具有相同属性的对象。其工作原理如下:

title.asterisk <- function(myTable){ do some stuff to 'myTable' }
这没关系,但您的代码仍然有点难以理解,因为实际上有两个不同的“myTable”对象,一个是全局对象,一个是局部对象。许多程序员通过在变量参数前添加句点“.”来解决这一问题,如下所示:

title.asterisk <- function(myTable){
    do some stuff to 'myTable'
    return(myTable)
}
myTable <- title.asterisk(myTable)
title.asterisk <- function(.myTable){
    do some stuff to '.myTable'
    return(.myTable)
}
myTable <- title.asterisk(myTable)

title.asterisk对于未来寻求简单方法(不知道是否更合适)解决此问题的任何人:

在函数内部,创建对象以临时保存要更改的对象的修改版本。使用
deparse(substitute())
获取传递给函数参数的变量的名称,然后使用
assign()
覆盖对象。需要使用
envir=parent.frame()
inside
assign()
允许在函数外部的环境中定义对象

title.asterisk <- function(){ do some stuff to 'myTable' }
(MyTable <- 1:10)

(MyTable)对象类型是什么您的
myTable
对象的属性,如果是,您首先使用什么函数来设置属性?好吧,我更感兴趣的是一般的答案,尽管我现在正在修改的实际表是descr包中的一个交叉表。标签是在创建对象时设置的,我说的是“attr”(待定$t,'dimnames')[[2][level.index]=paste0(level.val,marker)”给其中一个添加星号。@MikeBlyth我已经为您写了一个通用的答案,您可能会发现它很有用,即使它可能无法完全解决您的问题。我希望它有助于您过渡到R。感谢您的快速回答。如果我从您链接的相关问题中正确理解,“R中的替换函数是什么?”,它们只是文章结尾x-Wise评论的语法糖——绝对值得a+1。感谢您的精彩解释。由于Ruby的大量灌输,我几乎没有想到全局变量可以在函数中修改,一想到它就不寒而栗。但不同的语言需要不同的技术,所以这是很好的保持我的袖子为R。
title.asterisk <- function(){ do some stuff to 'myTable' }
(MyTable <- 1:10)
title.asterisk <- function(table) {
  tmp.table <- paste0(table, "*")
  name      <- deparse(substitute(table))
  assign(name, tmp.table, envir = parent.frame())
}

(title.asterisk(MyTable))