如何按列表中的项目名称保存绘图
How to save plots by names of items in a list
我可以保存一堆图,但它将它们命名为每个列表项的第一个值而不是变量的名称。
delm2<-data.frame(N = c(5.881, 5.671, 7.628, 4.643, 6.598, 4.485, 4.465, 4.978, 4.698, 3.685, 4.915, 4.983, 3.288, 5.455, 5.411, 2.585, 4.321, 4.661),
t1 = c("N", "N", "T", "T", "N", "N", "T", "N", "N", "N", "N", "T", "T", "T", "T", "T", "T", "N"),
t3 = c("r","v", "r", "v", "v", "r", "c", "c", "v", "r", "c", "c", "r", "v","c", "r", "v", "c"),
B = c(1.3, 1.3, 1.33, 1.25, 1.4, 1.34, 1.36, 1.39, 1.36, 1.42, 1.38, 1.31, 1.37, 1.44, 1.22, 1.4, 1.46, 1.35))
library(boot)
lapply(as.list(delm2[,c('N','B')]),
function(i){
bmp(filename = paste0(i,".bmp"), width = 350, height = 400)
glm.diag.plots(glm(i ~ t1*t3,data=del))
dev.off()
})
这会保存图,但它们是用数据中的数值命名的,而不是 lapply
的每个目标的名称...
即当前输出是两个名为“5.881”和“1.3”的文件,当我想要相同的两个文件但名为 "N" 和 "B"
我想我可以将 paste0(i,".bmp")
更改为 paste0(names(i),".bmp")
但这只是保存了第一个,根本没有名字。
看起来你可以在 How to save and name multiple plots with R 中给出仅是整数的名称,但我想要列表中变量的名称或 delm2 中的两个数字 N
和 B
.
从 Saving a list of plots by their names() 看来,使用 ggplot
输出会更容易,但 ggsave
在一个 glm.diag.plots
输出上不起作用。
(忽略我之前使用 Map
的建议。)
最大的收获是如何动态推导公式。一种方法是使用 as.formula
,它接受一个字符串并将其转换为可以在模型生成函数中使用的公式(例如)。
使用 lapply(as.list(delm2[,c('N','B')]), ...)
的一个问题是数据的其余部分(即列 t1
和 t3
)不会被传递,一次只传递一个向量。 (我想知道您对 del
的引用是否是错字、un-released/hidden 数据或其他原因。)
试试这个:
lapply(c("N", "B"), function(nm) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
dev.off()
})
总的来说,我不喜欢在这些函数中破坏作用域。也就是说,当我可以很容易地传递数据时,我尽量不去 lapply
之外获取数据。上面的迂腐语言可能看起来像:
lapply(c("N", "B"), function(nm, x) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
dev.off()
}, x = delm2)
虽然这保留了范围,但如果您不了解正在发生的事情,可能会感到困惑。
这可能是使用 for
而不是 *apply*
函数之一的好时机。你想要的一切都有副作用,并且由于 for
和 *apply
实际上是相同的速度,你获得了可读性:
for (nm in c("N", "B")) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
dev.off()
}
(本例中没有"scope breach",所以我使用了原来的变量。)
附带地,以配合我现在编辑的错误答案,其中包括 Map
。这是一个使用 Map
的示例,它可以更多地展示 Map
(和 mapply
)正在做什么,反之实际上可以改善您的即时需求。
如果出于某种原因你想让它们命名为不同于 "N.bmp"
的东西,你可以这样做:
Map(function(fn, vn, x) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
dev.off()
}, c("N2.bmp", "b3456.bmp"), c("N", "B"), list(delm2))
这里有两点需要注意:
list(delm2)
的用途是将该结构包装成单个 "thing",重复传递给映射函数。如果我们只做 delm2
(没有 list(...)
),那么它将尝试将 delm2
的第一列与每个第一个元素一起使用。这在其他情况下可能很有用,但在您的 glm
示例中,您需要存在其他列,因此您不能一次只包含一列。 (好吧,也有办法做到这一点......但目前很重要。)
- 第一次调用匿名函数,
fn
为"N2.bmp"
,vnis
"N", and
xis the full dataset of
delm2. The second time the anon-func is called,
fnis
"b3456.bmp",
vnis
"B", and
xis again the full dataset of
delm2`.
我将这部分标记为 "parenthetic" 因为它确实不会增加 这个 问题,但是自从我在我的第一个答案中开始那样,我想我会继续使用方法论,我选择 Map
的 "why"。最后,我认为 for
解决方案或 lapply
解决方案之一应该适合您。
我可以保存一堆图,但它将它们命名为每个列表项的第一个值而不是变量的名称。
delm2<-data.frame(N = c(5.881, 5.671, 7.628, 4.643, 6.598, 4.485, 4.465, 4.978, 4.698, 3.685, 4.915, 4.983, 3.288, 5.455, 5.411, 2.585, 4.321, 4.661),
t1 = c("N", "N", "T", "T", "N", "N", "T", "N", "N", "N", "N", "T", "T", "T", "T", "T", "T", "N"),
t3 = c("r","v", "r", "v", "v", "r", "c", "c", "v", "r", "c", "c", "r", "v","c", "r", "v", "c"),
B = c(1.3, 1.3, 1.33, 1.25, 1.4, 1.34, 1.36, 1.39, 1.36, 1.42, 1.38, 1.31, 1.37, 1.44, 1.22, 1.4, 1.46, 1.35))
library(boot)
lapply(as.list(delm2[,c('N','B')]),
function(i){
bmp(filename = paste0(i,".bmp"), width = 350, height = 400)
glm.diag.plots(glm(i ~ t1*t3,data=del))
dev.off()
})
这会保存图,但它们是用数据中的数值命名的,而不是 lapply
的每个目标的名称...
即当前输出是两个名为“5.881”和“1.3”的文件,当我想要相同的两个文件但名为 "N" 和 "B"
我想我可以将 paste0(i,".bmp")
更改为 paste0(names(i),".bmp")
但这只是保存了第一个,根本没有名字。
看起来你可以在 How to save and name multiple plots with R 中给出仅是整数的名称,但我想要列表中变量的名称或 delm2 中的两个数字 N
和 B
.
从 Saving a list of plots by their names() 看来,使用 ggplot
输出会更容易,但 ggsave
在一个 glm.diag.plots
输出上不起作用。
(忽略我之前使用 Map
的建议。)
最大的收获是如何动态推导公式。一种方法是使用 as.formula
,它接受一个字符串并将其转换为可以在模型生成函数中使用的公式(例如)。
使用 lapply(as.list(delm2[,c('N','B')]), ...)
的一个问题是数据的其余部分(即列 t1
和 t3
)不会被传递,一次只传递一个向量。 (我想知道您对 del
的引用是否是错字、un-released/hidden 数据或其他原因。)
试试这个:
lapply(c("N", "B"), function(nm) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
dev.off()
})
总的来说,我不喜欢在这些函数中破坏作用域。也就是说,当我可以很容易地传递数据时,我尽量不去 lapply
之外获取数据。上面的迂腐语言可能看起来像:
lapply(c("N", "B"), function(nm, x) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
dev.off()
}, x = delm2)
虽然这保留了范围,但如果您不了解正在发生的事情,可能会感到困惑。
这可能是使用 for
而不是 *apply*
函数之一的好时机。你想要的一切都有副作用,并且由于 for
和 *apply
实际上是相同的速度,你获得了可读性:
for (nm in c("N", "B")) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
dev.off()
}
(本例中没有"scope breach",所以我使用了原来的变量。)
附带地,以配合我现在编辑的错误答案,其中包括 Map
。这是一个使用 Map
的示例,它可以更多地展示 Map
(和 mapply
)正在做什么,反之实际上可以改善您的即时需求。
如果出于某种原因你想让它们命名为不同于 "N.bmp"
的东西,你可以这样做:
Map(function(fn, vn, x) {
bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
dev.off()
}, c("N2.bmp", "b3456.bmp"), c("N", "B"), list(delm2))
这里有两点需要注意:
list(delm2)
的用途是将该结构包装成单个 "thing",重复传递给映射函数。如果我们只做delm2
(没有list(...)
),那么它将尝试将delm2
的第一列与每个第一个元素一起使用。这在其他情况下可能很有用,但在您的glm
示例中,您需要存在其他列,因此您不能一次只包含一列。 (好吧,也有办法做到这一点......但目前很重要。)- 第一次调用匿名函数,
fn
为"N2.bmp"
,vnis
"N", and
xis the full dataset of
delm2. The second time the anon-func is called,
fnis
"b3456.bmp",
vnis
"B", and
xis again the full dataset of
delm2`.
我将这部分标记为 "parenthetic" 因为它确实不会增加 这个 问题,但是自从我在我的第一个答案中开始那样,我想我会继续使用方法论,我选择 Map
的 "why"。最后,我认为 for
解决方案或 lapply
解决方案之一应该适合您。