r - 修改 S3 对象而不返回它?

标签 r r-s3

我是 R 中面向对象编程的新手,并且正在努力解决如何正确编写修改对象的函数。

这个例子有效:

store1 <- list(
  apples=3,
  pears=4,
  fruits=7
)
class(store1) <- "fruitstore"
print.fruitstore <- function(x) {
  paste(x$apples, "apples and", x$pears, "pears", sep=" ")
}
print(store1)
addApples <- function(x, i) {
x$apples <- x$apples + i
x$fruits <- x$apples + x$pears
return(x)
}
store1 <- addApples(store1, 5)
print(store1)

但我想应该有一种更简洁的方法来做到这一点,而无需返回整个对象:
addApples(store1, 5)  # Preferable line...
store1 <- addApples(store1, 5)  # ...instead of this line

在 R 中编写修改函数的正确方法是什么? “<<-”?

更新:感谢大家在 R 中成为 OOP 的 Rosetta Stone。非常有用。
我试图解决的问题在流程方面非常复杂,因此引用类的刚性可能会给结构带来帮助。我希望我能接受所有的回答作为答案,而不仅仅是一个。

最佳答案

这是一个引用类实现,正如其中一条评论中所建议的那样。基本思想是建立一个名为 Stores 的引用类,它具有三个字段: applespearsfruits (编辑为访问器方法)。 initialize 方法用于初始化一个新的 store,addApples 方法将苹果添加到 store 中,而 show 方法相当于其他对象的 print

Stores = setRefClass("Stores", 
  fields = list(
    apples = "numeric",
    pears  = "numeric",
    fruits = function(){apples + pears}
  ), 
  methods = list(
    initialize = function(apples, pears){
      apples <<- apples
      pears <<- pears
    },
    addApples = function(i){
      apples <<- apples + i
    },
    show = function(){
      cat(apples, "apples and", pears, "pears")
    }
  )
)

如果我们初始化一个新的 store 并调用它,这就是我们得到的
FruitStore = Stores$new(apples = 3, pears = 4)
FruitStore

# 3 apples and 4 pears

现在,调用 addApples 方法,让我们向商店添加 4 个苹果
FruitStore$addApples(4)
FruitStore

# 7 apples and 4 pears

编辑。根据 Hadley 的建议,我更新了我的答案,以便 fruits 现在是一个访问器方法。当我们向商店添加更多 apples 时,它​​会保持更新。谢谢@hadley。

关于r - 修改 S3 对象而不返回它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21243359/

相关文章:

R S3 类 : Decide between overwriting vs appending the class name of the class attribute

r - 在 S3*data.frame 上调度自定义方法

r - 检查 S3 通用/方法一致性......警告

r - 坚持自动绘图 S3 方法的定义

r - 从第二个数据帧注释 ggplot2

r - 在生态记录中查找和计数音频丢失

r - 是什么导致R脚本被杀死?

r - 相同标签的相同颜色的 donut chart

r - 将字符数据拆分为数字和字母

r - 如何将 S3 方法声明为默认加载环境?