2016-07-08 8 views
2

Angenommen, ich habe eine Klasse S4Wie können S4-Slots aus anderen Slots prototypisiert (initialisiert) werden?

setClass("Person", representation(name = "character", first_letter = "character") 

und ich möchte den Schlitz Autofill first_letter, wenn ein Objekt ausgelöst wird. So etwas wie

> jack <- new("Person", name = "Jack") 
> print(jack) 
# Slot "name": 
# "Jack" 
# 
# Slot "first_letter": 
# "J" 

ich glaube, ich sollte etwas tun:

setClass("Person", 
    representation(name = "character", first_letter = "character"), 
    prototype(first_letter = substring([email protected], 1, 1)) 
) 

Natürlich, ich könnte ein Verfahren schreiben diese in einer gesonderten Erklärung zu tun. Ich bin speziell an dem Fall interessiert, in dem der -Steckplatz mit Informationen von einem anderen Steckplatz beim Aufrufen von new initialisiert wird.

Jede Hilfe wird sehr geschätzt!

Antwort

2

Eine Möglichkeit, die first_letter als privates Feld zu sehen ist.

  1. einen benutzerdefinierten Konstruktor erstellen (initiate), der die privaten Felder mit anderen öffentlichen Bereichen gesetzt
  2. /für öffentliche Slots bekommen Define stellen Sie die gleiche Logik zu halten, wenn Sie von der anderen Feld ändern.

Hier ist eine Implementierung:

## Note the use of `.` for private field 
## this is just a convention 
Person <- setClass("Person", representation(Name = "character", 
              first_letter. = "character")) 

## define setter and getter for public slots 
setGeneric("Name", function(x) standardGeneric("Name")) 
setMethod("Name","Person",function(x) [email protected]) 
setGeneric("Name<-", function(x,value) standardGeneric("Name<-")) 
setMethod("Name<-","Person",function(x,value){ 
    [email protected] <- value 
    [email protected]_letter. <- substring(value, 1, 1) 
    x 
}) 
## define the constructor 
## Note that we don't give an argument to the ctor 
## to init the private field 
setMethod ("initialize", signature = "Person", 
      definition = function (.Object, 
            name) { 
      [email protected] <- name 
      [email protected]_letter. <- substring(name, 1, 1) 
      return (.Object) 
      }) 

Nun, diese Prüfung durch Erstellen eines Objekts:

> p <- Person(name="Amine") 
> p 
An object of class "Person" 
Slot "Name": 
[1] "Amine" 
## the slot is automatically initialized 
Slot "first_letter.": 
[1] "A" 

Dann ist, dass wir den Schlitzwert ändern:

> Name(p) <- "Xvalue" 
> p 
An object of class "Person" 
Slot "Name": 
[1] "Xvalue" 
## Again the private slot is updated 
Slot "first_letter.": 
[1] "X" 
+0

Wow, das ist unglaublich! Ich schätze das wirklich! : D – nev

1

Mit dem Parameter können Sie Ihren Objektsteckplätzen Standardwerte zuweisen. Aber wie Sie beabsichtigen, eine Art der Vorverarbeitung der Daten zu tun, bevor Sie sie den Steckplätzen in Ihrem Objekt zuweisen, müssen Sie eine Methode für Ihre Klasse definieren.

Auch sollten Sie die slot Parameter verwenden ... representation das gleiche funktioniert, aber es ist für S3 Vererbung gedacht, die ich nicht sicher bin, ist das, was Sie beabsichtigen, (überprüfen ?setClass)

Dann definieren Sie Ihre Klasse

setClass ("Person", slots = c (name = "character", first_letter = "character")) 

oder

setClass("Person", representation (name = "character", first_letter = "character")) 

und die initia lisation Methode:

setMethod ("initialize", signature = "Person", 
      definition = function (.Object, 
            name, 
            first_letter = substring (name, 1, 1)) { 
       [email protected] <- name 
       [email protected]_letter <- first_letter 
       return (.Object) 
      }) 

Hinweis: die .Object muss so (gleiche Namen in der generic Methode definiert) aufgerufen werden. auch in der Regel müssen Sie es zu return erinnern ...

Jetzt sollten Sie in der Lage sein, zu initialisieren, wie Sie

wollen
new("Person", name = "Jack") 
Verwandte Themen