在 mapply 调用中使用计数器访问命名列表元素作为 ggtitle

use a counter to access named list elements as ggtitle within mapply call

我正在根据来自两个列表的数据生成和绘制多个 ggplot,因此我使用 mapply。其中一个列表具有命名元素,我想将其用作 ggtitle。但它只需要所有图的第一个元素

> names(sample_subset_list)
[1] "water after day 43 dna min reads per OTU 5"
[2] "biofilm after day 43 dna min reads per OTU 5"
[3] "water after day 43 cdna min reads per OTU 5"
[4] "biofilm after day 43 cdna min reads per OTU 5"
[5] "water after day 44 dna min reads per OTU 5"
[6] "biofilm after day 44 dna min reads per OTU 5"
[7] "water after day 44 cdna min reads per OTU 5"
[8] "biofilm after day 44 cdna min reads per OTU 5"

这是绘图函数:

ordination_plots <- list()
counter <- 0
ordination_plots <- mapply(function(x,y,counter) {
                        counter <- counter + 1 
                        plot_ordination(x, y, type = "sample") + 
                            ggtitle(names(sample_subset_list)[counter]) +
}, x = sample_subset_list, y = ordination_nmds, counter = 0, SIMPLIFY = FALSE)

这将为我提供标题始终是

的第一个元素的情节

names(sample_subset_list)

调用 ggtitle(names(sample_subset_list)[]) +

时也是如此

如果我使用 counter <<-(此处建议:Using a counter inside an apply structured loop in R)或像

这样调用 ggtitle

ggtitle(names(sample_subset_list)) +

ggtitle(names(sample_subset_list)[[]]) +

我根本没有头衔。

我开始时没有计数器,这也给了我所有情节相同的标题。有人可以向我解释如何遍历列表元素的名称以将它们用于 ggplots 吗?

让我们降低示例的复杂性:

counter <- 0

invisible(mapply(function(letter, counter) {

  counter <- counter + 1
  cat("Letter: ", letter, "; Counter: ", counter, "\n", sep="")

}, letters[1:10], counter))

注意:我只使用 invisible() 来停止打印 mapply() 的结果。

letters[1:10]是小写字母的10元素向量(内置数据)。

您在 mapply() 之外定义了 counter。与 forwhile 不同,mapply() 中的函数默认情况下不会在父作用域(mapply() 之外)创建或修改变量,因此结果如下:

Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1

将带有信息的第二个参数传递给 mapply() 的函数参数是可以的,但是如果意图是在 [=15= 的函数范围之外增加一些东西的副作用] 那么你真的不应该将它作为参数传递给 in 并只使用 <<- 运算符修改它,根据帮助页面:

"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."

所以,我们可以这样做:

# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

  counter <<- counter + 1
  cat("Letter: ", letter, "; Counter: ", counter, "\n", sep="")

}, letters[1:10]))

得到这个:

Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10

该评论不是为了 snark。您正在使用的副作用可能对您未来的自己或与您共享代码的人来说并不明显,因此请注意它会帮助您重新弄清楚并让他们弄清楚发生了什么。