【发布时间】:2020-02-09 14:36:31
【问题描述】:
我有一些数据(鸢尾花数据集),还有一个名为decisionplot 的绘图函数。我的问题是如何将decisionplot 函数(输出ggplot 图)应用于我数据中的所有变量组合。也就是在我们拥有的iris数据集中;
"Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
我想将函数decisionplot应用于以下组合:
"Sepal.Length" "Sepal.Width"
"Sepal.Length" "Petal.Length"
"Sepal.Length" "Petal.Width"
"Sepal.Width" "Petal.Length"
"Sepal.Width" "Petal.Width"
"Petal.Length" "Petal.Width"
将这些绘图组合存储在一个列表中,我可以在一个网格上绘制不同的输出。
数据和decisionplot函数如下:
data(iris)
df <- iris %>%
filter(Species != "setosa") %>%
mutate(Species = +(Species == "virginica"))
decisionplot <- function(model, data, class = NULL, model_type = "NA", predict_type = "class",
resolution = 300, main, showgrid = TRUE, ...) {
if(!is.null(class)){
cl <- data[,class]
}
else{
cl <- 1
}
k <- length(unique(cl))
# make grid
r <- sapply(data[,1:2], 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)
if(model_type == "xgboost"){
message(paste0("Running Model ", model_type))
p <- predict(object = model, newdata = xgboost::xgb.DMatrix(data = as.matrix(g)), type = predict_type)
#p <- ifelse(p > tail(sort(p),1000)[1000], "Bankrupt", "Non-Bankrupt")
p <- ifelse(p > 0.50, "Bankrupt", "Non-Bankrupt")
}
else {
message(paste0("Running Model ", model_type))
p <- predict(model, g, type = predict_type)
}
if(is.list(p)) p <- p$class
if(is.logical(p)) p <- ifelse(p == TRUE, "Non-Bankrupt", "Bankrupt")
p <- as.factor(p)
plot_data <- cbind(g, p) %>%
setNames(c("X1", "X2", "Y")) %>%
mutate(class_num = case_when(
Y == "Non-Bankrupt" ~ 1,
Y == "Bankrupt" ~ 2
))
ggplot() +
geom_point(aes(x = X1, y = X2, colour = Y),
data = plot_data) +
geom_contour(aes(x = X1, y = X2, z = class_num),
bins = 2,
data = plot_data, size = 0.001) +
geom_point(aes(x = Xvar1, y = Xvar2, color = factor(Yvar)),
size = 3,
data = data) +
geom_point(aes(x = Xvar1, y = Xvar2),
size = 3,
shape = 1,
#alpha = 0.2,
data = data) +
labs(title = paste(main),
x = var1_to_plot,
y = var2_to_plot)
}
然后我设置我想要通过函数的变量并创建我的boundary_data:
var1_to_plot = "Sepal.Length"
var2_to_plot = "Sepal.Width"
boundary_data <- df %>%
dplyr::select(rlang::eval_tidy(var1_to_plot), rlang::eval_tidy(var2_to_plot), Species) %>%
mutate(Species = factor(Species)) %>%
setNames(c("Xvar1", "Xvar2", "Yvar")) %>%
data.frame()
我终于创建了我的逻辑模型并运行decisionplot 函数。
model <- glm(Yvar ~., data = boundary_data, family = binomial(link='logit'))
class(model) <- c("lr", class(model))
predict.lr <- function(object, newdata, ...)
predict.glm(object, newdata, type = "response") > .5
decisionplot(model, boundary_data, predict_type = "response", class = "Yvar", model_type = "Logistic", main = "Logistic Regression")
这给了我:
但是我想让它成为变量的所有组合之一(因为这里它只考虑Sepal.Width 和Sepal.Length)。
如何在网格上绘制不同的ggplot 变量组合?还是将图存储为列表?
编辑
我目前拥有以下内容 - 它为我提供了 12 个不同组合的列表。每个列表还有 2 个列表,一个数据集和一个逻辑模型。
var_combos <- expand.grid(colnames(df[,1:4]), colnames(df[,1:4])) %>%
filter(!Var1 == Var2)
iter_function = function(dat, V1, V2, Y){
data = dat %>%
select(rlang::eval_tidy(V1), rlang::eval_tidy(V2), Y) %>%
mutate(Y = factor(rlang::eval_tidy(Y)))
# Logistic Model
model = glm(rlang::eval_tidy(Y) ~ ., data = data, family = binomial(link = 'logit'))
class(model) <- c("lr", class(model))
predict.lr <- function(object, newdata, ...){
predict.glm(object, newdata, type = "response") > .5
}
return(list(data, model))
}
boundary_lists <- map2(
.x = var_combos$Var1,
.y = var_combos$Var2,
~iter_function(dat = df, V1 = .x, V2 = .y, Y = df$Species)
)
现在我想将这些列表中的每一个应用于decisionplot 函数。我不断收到. not found。
map2(
.x = .[[1]],
.y = .[[2]],
~decisionplot(model = .x, data = .y, predict_type = "response", class = "Species", model_type = "Logistic", main = "Logistic Regression")
)
如何映射列表列表的功能? (我意识到我没有给它从iter_function() 创建的boundary_lists 列表)
【问题讨论】:
-
我将使用
gtools::combinations生成所有成对组合,然后使用purrr::pmap迭代所有组合以应用您的函数并生成绘图。这将为您提供一个绘图列表,您可以将其用作cowplot::plot_grid等函数的输入。 -
@rpolicastro 或者地块列表也可以很容易地与
patchwork::wrap_plots一起使用 -
我有所有不同的组合使用
var_combos <- expand.grid(colnames(df[,1:4]), colnames(df[,1:4])) %>% filter(!Var1 == Var2)- 我只是在想如何最好地提取每一行和pmap每个组合来构造一个新数据框列表,这将是一个@列表987654350@ 数据帧。 -
我几乎拥有它(我添加了一个 EDIT)。我现在只需要知道如何使用
map2()映射列表的第一个和第二个元素。