dputting an S4 object

前端 未结 1 894
盖世英雄少女心
盖世英雄少女心 2020-12-19 05:42

How would a person dput() an S4 object? I tried this

require(sp)
require(splancs)
plot(0, 0, xlim = c(-100, 100), ylim = c(-100, 100))
poly.d &l         


        
相关标签:
1条回答
  • 2020-12-19 05:58

    As it currently stands, you cannot dput this object. The code of dput contains the following loop:

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

    This handles S4 objects recursively, but it relies on the assumption an S3 object will not contain an S4 object, which in your example does not hold:

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

    Edit: Here is a work-around the limitations of dput. It works for the example you provided, but I don't think that it will work in general (e.g. it does not handle attributes).

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

    And here it is in action:

    > dput2(poly.d,file=(tempFile <- tempfile()))
    > poly.d2 <- dget(tempFile)
    > all.equal(poly.d,poly.d2)
    [1] TRUE
    
    0 讨论(0)
提交回复
热议问题