R如何在函数调用中处理对象?

Der*_*ang 8 r object

我有Java和Python的背景,我最近在学习R.

今天我发现R似乎处理的对象与Java和Python完全不同.

例如,以下代码:

x <- c(1:10)
print(x)
sapply(1:10,function(i){
            x[i] = 4
        })
print(x)
Run Code Online (Sandbox Code Playgroud)

代码给出以下结果:

[1]  1  2  3  4  5  6  7  8  9 10
[1]  1  2  3  4  5  6  7  8  9 10
Run Code Online (Sandbox Code Playgroud)

但我希望第二行输出全部为'4',因为我修改了sapply函数中的向量.

那么这是否意味着R在函数调用中复制对象而不是引用对象?

G. *_*eck 18

x 是在全局环境中定义的,而不是在您的函数中定义的.

如果您尝试修改非本地对象(如x函数中),则R会生成对象的副本并修改副本,因此每次运行匿名函数时,都会生成副本,x并将其第i个组件设置为4.该函数退出已制作的副本永远消失.原件x未修改.

如果我们要写x[i] <<- i或者如果我们要写,x[i] <- 4; assign("x", x, .GlobalEnv)那么R会把它写回来.将其写回的另一种方法是设置e,例如,x存储在其中的环境并执行此操作:

e <- environment()
sapply(1:10, function(i) e$x[i] <- 4)
Run Code Online (Sandbox Code Playgroud)

或者可能这样:

sapply(1:10, function(i, e) e$x[i] <- 4, e = environment())
Run Code Online (Sandbox Code Playgroud)

通常一个人不会在R中编写这样的代码.而是将结果作为函数的输出生成,如下所示:

x <- sapply(1:10, function(i) 4)
Run Code Online (Sandbox Code Playgroud)

(实际上在这种情况下,人们可以写x[] <- 4.)

添加:

使用proto包可以做到这一点,其中方法fx属性的第i个组件设置为4.

library(proto)

p <- proto(x = 1:10, f = function(., i) .$x[i] <- 4)

for(i in seq_along(p$x)) p$f(i)
p$x
Run Code Online (Sandbox Code Playgroud)

添加:

上面添加了另一个选项,我们在其中明确传递x存储的环境.

  • 在函数式语言中,函数不能有副作用.R不是那么严格,但R函数限制副作用仍然是正确的.它更好地以预期使用的方式工作,而不是像用另一种语言写作一样.有几个对象系统(S3,S4,参考类).S3是最常用的.S4要复杂得多.参考类是最近添加的.您可能希望特别探索参考类.还有一些用户提供的包提供不同的范例:proto和R.oo(可能还有其他). (3认同)

Ana*_*liy 7

你是对的.检查R语言定义:4.3.3参数评估

AFAIK,R在您尝试修改数据之前并不真正复制数据,因此遵循写时复制语义.