2010-08-12 6 views
7

Wie würde eine Person dput() ein S4-Objekt? Ich habe versucht, dieseein S4-Objekt spenden

require(sp) 
require(splancs) 
plot(0, 0, xlim = c(-100, 100), ylim = c(-100, 100)) 
poly.d <- getpoly() #draw a pretty polygon - PRETTY! 
poly.d <- rbind(poly.d, poly.d[1,]) # close the polygon because of Polygons() and its kin 
poly.d <- SpatialPolygons(list(Polygons(list(Polygon(poly.d)), ID = 1))) 
poly.d 
dput(poly.d) 

Beachten Sie, dass, wenn ich dput() ein S4-Objekt, kann ich es nicht wieder rekonstruieren. Ihre Gedanken?

+1

Warum wollen Sie Objekte auf diese Weise bauen? Es scheint, als wäre es viel weniger lesbar als das Schreiben einer Funktion, die ein Vorlagenobjekt erstellt und zurückgibt, das Sie dann anpassen können. – Vince

+0

Es ist nur etwas, was mir aufgefallen ist, als ich versucht habe, ein kleines Polygon zu Testzwecken zu speichern. Ich stimme zu, dass es einfacher ist, eine n * 2-Matrix und eine Funktion zu haben, die ein wenig jongliert. –

Antwort

9

Wie es derzeit steht, können Sie nicht dieses Objekt dput. Der Code von dput enthält folgende Schleife:

if (isS4(x)) { 
    cat("new(\"", class(x), "\"\n", file = file, sep = "") 
    for (n in slotNames(x)) { 
     cat(" ,", n, "= ", file = file) 
     dput(slot(x, n), file = file, control = control) 
    } 
    cat(")\n", file = file) 
    invisible() 
} 

Diese Griffe S4 Objekte rekursiv, aber es beruht auf der Annahme, ein S3-Objekt nicht ein S4-Objekt enthalten, die in Ihrem Beispiel nicht gilt:

> isS4(slot(poly.d,'polygons')) 
[1] FALSE 
> isS4(slot(poly.d,'polygons')[[1]]) 
[1] TRUE 

Bearbeiten: Hier ist ein Work-Around die Einschränkungen von dput. Es funktioniert für das von Ihnen bereitgestellte Beispiel, aber ich denke nicht, dass es im Allgemeinen funktioniert (z. B. behandelt es keine Attribute).

dput2 <- function (x, 
        file = "", 
        control = c("keepNA", "keepInteger", "showAttributes")){ 
    if (is.character(file)) 
     if (nzchar(file)) { 
      file <- file(file, "wt") 
      on.exit(close(file)) 
     } 
     else file <- stdout() 
    opts <- .deparseOpts(control) 
    if (isS4(x)) { 
     cat("new(\"", class(x), "\"\n", file = file, sep = "") 
     for (n in slotNames(x)) { 
      cat(" ,", n, "= ", file = file) 
      dput2(slot(x, n), file = file, control = control) 
     } 
     cat(")\n", file = file) 
     invisible() 
    } else if(length(grep('@',capture.output(str(x)))) > 0){ 
     if(is.list(x)){ 
     cat("list(\n", file = file, sep = "") 
     for (i in 1:length(x)) { 
      if(!is.null(names(x))){ 
      n <- names(x)[i] 
      if(n != ''){ 
       cat(" ,", n, "= ", file = file) 
      } 
      } 
      dput2(x[[i]], file = file, control = control) 
     } 
     cat(")\n", file = file) 
     invisible() 
     } else { 
     stop('S4 objects are only handled if they are contained within an S4 object or a list object') 
     } 
    } 
    else .Internal(dput(x, file, opts)) 
} 

Und hier ist es in Aktion:

> dput2(poly.d,file=(tempFile <- tempfile())) 
> poly.d2 <- dget(tempFile) 
> all.equal(poly.d,poly.d2) 
[1] TRUE 
+0

Enorm hilfreich für mich! Vielen Dank. Ein Fix wurde benötigt: Diese Zeile wurde vor dem letzten rekursiven Aufruf von dput2 hinzugefügt: 'if (i> 1) cat (", ", file = file)' – Roger

Verwandte Themen