2010-08-12 10 views
7

¿Cómo podría una persona dput() un objeto S4? Probé este Avisodputting a S4 object

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) 

que si un objeto dput() S4, no puedo reconstruirlo de nuevo. ¿Tus pensamientos?

+1

¿Por qué quiere construir objetos de esta manera? Parece que sería mucho menos legible que escribir una función que construye y devuelve un objeto de plantilla que luego puede ajustar. – Vince

+0

Es algo que noté cuando traté de guardar un pequeño polígono para realizar pruebas. Estoy de acuerdo en que es más fácil tener una matriz n * 2 y una función que hace un poco de malabares con ella. –

Respuesta

9

Tal como está actualmente, no se puede dput este objeto. El código de dput contiene el siguiente bucle:

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() 
} 

Este maneja S4 objetos de forma recursiva, pero se basa en la suposición de un objeto S3 no contendrá un objeto S4, que en su ejemplo no se sostiene:

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

Edit: Aquí está una solución temporal a las limitaciones de dput. Funciona para el ejemplo que proporcionó, pero no creo que funcione en general (por ejemplo, no maneja atributos).

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)) 
} 

y aquí está en acción:

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

¡Enormemente útil para mí! Gracias. Se necesitaba una solución: agregó esta línea antes de la última llamada recursiva a dput2: 'if (i> 1) cat (", ", file = file)' – Roger