首页 > 解决方案 > R:将 grob 对象转换为 ggplot/plotly

问题描述

我使用 R 编程语言。我正在尝试将“grob”对象转换为“ggplot”对象(目标最终是将 ggplot 对象转换为“plotly”对象)。

我正在寻找将“grob”转换为“ggplot”的“最简单”的方法——我使用的计算机没有 USB 端口或互联网连接,它只有 R 和一些预加载的库(例如 ggplot2、ggpubr)

在我的示例中:我生成了一些数据,运行了一个统计模型(“随机森林”)并使用“压缩”轴(“Tsne”)绘制了结果。下面的代码可以复制/粘贴到 R 中,生成的“绘图”(“final_plot”)是我要转换为“ggplot”的对象:

 library(cluster)
library(Rtsne)
library(dplyr)

library(randomForest)
library(caret)
library(ggplot2)
library(plotly)


#PART 1 : Create Data

#generate 4 random variables : response_variable ~ var_1 , var_2, var_3

var_1 <- rnorm(10000,1,4)
var_2<-rnorm(10000,10,5)
var_3 <- sample( LETTERS[1:4], 10000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.05) )
response_variable <- sample( LETTERS[1:2], 10000, replace=TRUE, prob=c(0.4, 0.6) )


#put them into a data frame called "f"
f <- data.frame(var_1, var_2, var_3, response_variable)

#declare var_3 and response_variable as factors
f$response_variable = as.factor(f$response_variable)
f$var_3 = as.factor(f$var_3)

#create id
f$ID <- seq_along(f[,1])

#PART 2: random forest

#split data into train set and test set
index = createDataPartition(f$response_variable, p=0.7, list = FALSE)
train = f[index,]
test = f[-index,]

#create random forest statistical model
rf = randomForest(response_variable ~ var_1 + var_2 + var_3, data=train, ntree=20, mtry=2)

#have the model predict the test set
pred = predict(rf, test, type = "prob")
labels = as.factor(ifelse(pred[,2]>0.5, "A", "B"))
confusionMatrix(labels, test$response_variable)

#PART 3: Visualize in 2D (source: https://dpmartin42.github.io/posts/r/cluster-mixed-types)

gower_dist <- daisy(test[, -c(4,5)],
                    metric = "gower")

gower_mat <- as.matrix(gower_dist)

labels = data.frame(labels)
labels$ID = test$ID


tsne_obj <- Rtsne(gower_dist,  is_distance = TRUE)

tsne_data <- tsne_obj$Y %>%
    data.frame() %>%
    setNames(c("X", "Y")) %>%
    mutate(cluster = factor(labels$labels),
           name = labels$ID)

plot = ggplot(aes(x = X, y = Y), data = tsne_data) +
    geom_point(aes(color = labels$labels))

plotly_plot = ggplotly(plot)


a = tsne_obj$Y
a = data.frame(a)
data = a
data$class = labels$labels


decisionplot <- function(model, data, class = NULL, predict_type = "class",
                         resolution = 100, showgrid = TRUE, ...) {
    
    if(!is.null(class)) cl <- data[,class] else cl <- 1
    data <- data[,1:2]
    k <- length(unique(cl))
    
    plot(data, col = as.integer(cl)+1L, pch = as.integer(cl)+1L, ...)
    
    # make grid
    r <- sapply(data, range, na.rm = TRUE)
    xs <- seq(r[1,1], r[2,1], length.out = resolution)
    ys <- seq(r[1,2], r[2,2], length.out = resolution)
    g <- cbind(rep(xs, each=resolution), rep(ys, time = resolution))
    colnames(g) <- colnames(r)
    g <- as.data.frame(g)
    
    ### guess how to get class labels from predict
    ### (unfortunately not very consistent between models)
    p <- predict(model, g, type = predict_type)
    if(is.list(p)) p <- p$class
    p <- as.factor(p)
    
    if(showgrid) points(g, col = as.integer(p)+1L, pch = ".")
    
    z <- matrix(as.integer(p), nrow = resolution, byrow = TRUE)
    contour(xs, ys, z, add = TRUE, drawlabels = FALSE,
            lwd = 2, levels = (1:(k-1))+.5)
    
    invisible(z)
}


model <- randomForest(class ~ ., data=data, mtry=2, ntrees=500)

#this is the final plot
 final_plot = decisionplot(model, data, class = "class", main = "rf (1)")

从这里开始,我试图将此对象(“final_plot”)转换为 ggplot 对象:

library(ggpubr)
final = ggpubr::as_ggplot(final_plot)

但这给了我以下错误:

Error in gList(...) : only 'grobs' allowed in "gList"

从这里开始,我最终会想使用这个命令将 ggplot 转换为一个 plotly 对象:

plotly_plot = ggplotly(final)

有谁知道是否有一种直接的方法可以将“final_plot”转换为 ggplot 对象?(然后阴谋)?我没有 ggplotify 库。

谢谢

标签: rggplot2plotlydata-visualization

解决方案


推荐阅读