我在玩R中的S4对象,想知道以下内容:

让我们假设以下简化示例:R中有两个S4类,一个称为Customer,另一个称为Order。我们用以下插槽定义它们:

Customer <- setClass(Class = "Customer",slots = c(CustomerID = "numeric", Name = "character", OrderHistory = "data.frame"),
                     prototype = list(CustomerID = 0,Name = "",OderHistory = data.frame()))

Order <- setClass(Class = "Order",slots = c(CustomerID = "numeric", Description = "character",
                                               Cost = "numeric"),
                     prototype = list(CustomerID = 0,Description = "",Cost = 0))


# constructor

Customer <- function(CustomerID, Name, OrderHistory=data.frame()){
  #drop sanity checks
  new("Customer",CustomerID = CustomerID, Name = Name, OrderHistory = OrderHistory)
}

Order <- function(CustomerID, Description = "",Cost = 0){
  #drop sanity checks
  new("Order",CustomerID = CustomerID, Description = "", Cost = 0)
}

#create two objects

firstCustomer <- Customer(1,"test")

firstOrder <- Order(1,"new iPhone", 145)


显然,firstCustomer和firstOrder是通过CustomerID链接的。创建新的Order实例后,是否可以自动更新Customer的OrderHistory插槽?假设OrderHistory有两列,“ Description”和“ Cost”,如何自动更新一个新的订单实例?有没有一种优雅/通用的方法?订单类很可能需要一个类型为“客户”的广告位。提前谢谢了

最佳答案

您无法跨两个独立的对象进行链接,因此您需要同时使用两者的方法。这是替换方法的示例:

Customer <- setClass(
  "Customer",
  slots=c(
    CustomerID="numeric",
    Name="character",
    OrderHistory="list"
  ),
  prototype=list(OrderHistory = list())
)
Order <- setClass(
  Class="Order",
  slot =c(
    Description="character", Cost="numeric"
) )

setGeneric(
  "add<-",
  function(object, value, ...) StandardGeneric("add<-")
)
setMethod("add<-", c("Customer", "Order"),
  function(object, value) {
    object@OrderHistory <- append(object@OrderHistory, value)
    object
  }
)
setMethod("show", "Customer",
  function(object) {
    cat("** Customer #", object@CustomerID, ": ", object@Name, "\n\n", sep="")
    for(i in object@OrderHistory) cat("\t", i@Description, "\t", i@Cost, "\n", sep="")
  }
)

firstCustomer <- new("Customer", CustomerID=1, Name="test")
add(firstCustomer) <- new("Order", Description="new iPhone", Cost=145)
add(firstCustomer) <- new("Order", Description="macbook", Cost=999)

firstCustomer


产生:

** Customer #1: test

  new iPhone  145
  macbook 999

关于r - 如何在R中自动更新S4类的插槽,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29779909/

10-09 19:27