2017-08-28 30 views
1

與MongoDB的使用對象我有這樣的代碼:如何序列化/反序列化ggplot爲R中

for(plot in plotResults) { 
    .session$plots[[plot$id]] <- if (!is.null(plot[["grob"]])) { 
    plot[["grob"]] 
    } else { 
    plot[["plot"]] 
    } 
    ggsave(paste0(plot$id, ".png"), .session$plots[[plot$id]]) 
    ... 

}獲取生成

文件,但是當我保存ggplot對象使用該工具來蒙戈:

serializeObj <- function(obj) { 
    if (is.list(obj)) { 
    structure(lapply(obj, serializeObj), names = serializeNames(obj)) 
    } else { 
    rawToChar(serialize(obj, NULL, ascii = TRUE)) 
    } 
} 

deserializeObj <- function(obj) { 
    if (is.list(obj)) { 
    structure(lapply(obj, deserializeObj), names = unserializeNames(obj)) 
    } else if (is.serialized(obj)) { 
    unserialize(charToRaw(obj)) 
    } else { 
    obj 
    } 
} 

## Replaces characters illegal in Mongo names with "safe" substitutes 
safeNames <- function(value) { 
    gsub("\\.", "___DOT___", value) 
} 

## Replaces back "safe" substitutes 
unsafeNames <- function(value) { 
    gsub("___DOT___", ".", value) 
} 

serializeNames <- function(obj) { 
    lapply(names(obj), safeNames) 
} 

unserializeNames <- function(obj) { 
    lapply(names(obj), unsafeNames) 
} 

我跑serializeObj之前,我保存到蒙戈再後來deserializeObj從蒙戈讀取之後。讀取代替ggplot對象後,我得到了列表,我無法在該列表中調用ggsave。

我該如何序列化某種類型的對象,如ggplot,然後反序列化它以獲得相同的對象?

+0

ggplot是一個(嵌套的)列表。使用'str'來檢查。你的方法失去了屬性,最重要的是屬性。 – Roland

+0

@Roland有沒有辦法恢復類屬性? – jcubic

+1

'help(「attr」)'''help(「attributes」)',當然你需要先存儲它們。否則,我們正在談論一些子列表屬性的手動工作。 – Roland

回答

0

正如您的評論所指出的,您正在丟失有關ggplot對象的類的信息。您應該確保存儲這些信息,並在反序列化時恢復它。例如,我寫了三個簡單的f(x),可能有所幫助。

#### custom f(x)  
serializeGGClasses <- function(obj) { 
    serializeObj(sapply(obj, class)) 
} 

unserializeGGClasses <- function(obj) { 
    lapply(obj, (function(el) {unserialize(charToRaw(el)) })) 
} 

restoreGGClasses <- function(plot.obj, class.obj) { 
    class(plot.obj) <- c("gg", "ggplot") 
    for (i in 1:length(plot.obj)) { 
    class(plot.obj[[i]]) <- class.obj[[i]] 
    } 
    return(plot.obj) 
} 

### 

現在,您可以序列化ggplot對象的所有類,並將它們存儲在您的數據庫中。當你retrive的對象,您需要/還原它們

library(ggplot2)  
a<- qplot(1, 1) 
class(a)  # "gg"  "ggplot" 
is.list(a) # TRUE 

b <- serializeObj(a) 
b.class <- serializeGGClasses(a) 

# Unserialize 
c <- deserializeObj(b) 
c.class <- unserializeGGClasses(b.class) 

# Right now, "c" is just a list 
final.c <- restoreGGClasses(plot.obj = c, 
          class.obj = c.class) 

# "final.c" can be plotted 
final.c 
+0

不幸的是這不起作用,反序列化之後情節被搞亂了。遞歸方法是錯誤的。 – jcubic

0

這項工作,而不是遞歸串行解串器只需要一個級別,也沒有必要序列化的名字,因爲他們不必再點僅積嵌套數據有他們。

serializePlots <- function(data) { 
    lapply(data, function(plot) { 
    rawToChar(serialize(plot, NULL, ascii = TRUE)) 
    }) 
} 

unserializePlots <- function(data) { 
    lapply(data, function(obj) { 
    if (is.serialized(obj)) { 
     unserialize(charToRaw(obj)) 
    } else { 
     obj 
    } 
    }) 
}