在R中使用for循环和ggplot处理承诺(rlang)
此脚本的目的是复制类似下图的内容: 可在以下网址找到: 我遇到的问题与(我认为)R如何处理我在ggplot中的承诺有关 下面的例子再现了我的问题在R中使用for循环和ggplot处理承诺(rlang),r,ggplot2,rlang,R,Ggplot2,Rlang,此脚本的目的是复制类似下图的内容: 可在以下网址找到: 我遇到的问题与(我认为)R如何处理我在ggplot中的承诺有关 下面的例子再现了我的问题 library(tidyverse) process_starting_row <- 600 per_validation_period <- 30 number_of_validations <- 5 graphical_data <- data.frame(x= 1:(process_starting_row + 1 +
library(tidyverse)
process_starting_row <- 600
per_validation_period <- 30
number_of_validations <- 5
graphical_data <- data.frame(x= 1:(process_starting_row + 1 + (number_of_validations)*per_validation_period))
for (it in 1:number_of_validations) {
# For this graph there is always a line and then a colour component explaining each one...
graphical_data[,paste0("iteration",it,"line")] <- c(it)
# First make the whole row grey and then "dolly up" the colours.
graphical_data[,paste0("iteration",it,"colour")] <- "grey"
graphical_data[1:(process_starting_row + (it-1)*per_validation_period), paste0("iteration",it,"colour")] <- "blue"
graphical_data[(process_starting_row + 1 + (it)*per_validation_period), paste0("iteration",it,"colour")] <- "red"
}
#graphical_data
我希望迭代的就是这个基本对象
我编写了一个函数,它将添加每个迭代gg_adding()
,然后再添加另一个ggaddfor()
,运行for循环
gg_adding <- function(data, iteration_sub, color_sub){
iteration_promise <- enquo(iteration_sub)
colour_promise <- enquo(color_sub)
gg <- geom_point(data = data, aes(x= x, y= !! iteration_promise, color = !! colour_promise))
return(gg)
}
ggaddfor <- function(data, gg){
ggout <- gg
for (it in 1:number_of_validations) {
#print(it)
iterationsub <- paste0("iteration",it,"line")
coloursub <- paste0("iteration",it,"colour")
ggout <- ggout + gg_adding(data, iterationsub, coloursub)
}
return(ggout)
}
它生成的输出如下所示:
显然这不是我所希望的。。。
为了测试,我明确规定了每次迭代
# Working...
ggadd <- ggbase
ggadd <- ggadd + gg_adding(graphical_data, iteration1line, iteration1colour)
ggadd <- ggadd + gg_adding(graphical_data, iteration2line, iteration2colour)
ggadd <- ggadd + gg_adding(graphical_data, iteration3line, iteration3colour)
ggadd <- ggadd + gg_adding(graphical_data, iteration4line, iteration4colour)
ggadd <- ggadd + gg_adding(graphical_data, iteration5line, iteration5colour)
#正在工作。。。
ggadd对我有效的方法是将gg\u adding()
函数中的enquo()
调用替换为as.symbol()
,这样新函数将如下所示:
gg_adding <- function(data, iteration_sub, color_sub){
iteration_promise <- as.symbol(iteration_sub)
colour_promise <- as.symbol(color_sub)
gg <- geom_point(data = data, aes(x= x, y= !! iteration_promise, color = !! colour_promise))
return(gg)
}
我对整洁的评估和报价略知一二,但并不完全熟悉。我理解的是,无论您在aes()
中输入什么,都将在data
列名的上下文中进行计算,首先在层的数据中,然后在全局数据中,除非用户在其调用中是显式的(例如aes(fill=“black”)
或其他内容)。由于ggbase
构造中已经指定了x
和data
的值,因此在geom_point()
调用中不需要它
gg <- geom_point(aes(y= !! iteration_promise, color = !! colour_promise))
我知道这可能是一个不请自来的提示,我很抱歉,但ggplot似乎更喜欢使用长数据而不是宽数据。我对“宽”数据的意思是,您的迭代有点像cbind()
-ed。因此,如果您首先计算每个迭代,然后将它们一起计算,rbind()
new_gr_dat <- lapply(seq_len(number_of_validations), function(it){
df <- data.frame(x= 1:(process_starting_row + 1 + (number_of_validations)*per_validation_period),
line = it, # doubles as y-value and iteration tracker
colour = "grey")
df[1:(process_starting_row + (it-1)*per_validation_period), "colour"] <- "blue"
df[(process_starting_row + 1 + (it)*per_validation_period), "colour"] <- "red"
return(df)
})
new_gr_dat <- do.call(rbind, new_gr_dat)
ggplot(new_gr_dat, aes(x = x, y = line, colour = colour)) +
geom_point() +
coord_cartesian(xlim = c(process_starting_row-1*per_validation_period, max(new_gr_dat$x)))
new\u gr\u dat看起来您正在向参数传递字符串,例如ggadding()
中的iterationsub
。在这种情况下,一个选项是在ggadding()
函数中将enquo()
替换为sym()
。在您的测试用例中,您将参数作为符号而不是字符串进行传递,这就是为什么ggadding()
在这里可以正常工作的原因。@aosmith谢谢!这就解决了问题。这也使两者之间的区别更加明确。我感谢你的帮助。
gg <- geom_point(aes(y= !! iteration_promise, color = !! colour_promise))
new_gr_dat <- lapply(seq_len(number_of_validations), function(it){
df <- data.frame(x= 1:(process_starting_row + 1 + (number_of_validations)*per_validation_period),
line = it, # doubles as y-value and iteration tracker
colour = "grey")
df[1:(process_starting_row + (it-1)*per_validation_period), "colour"] <- "blue"
df[(process_starting_row + 1 + (it)*per_validation_period), "colour"] <- "red"
return(df)
})
new_gr_dat <- do.call(rbind, new_gr_dat)
ggplot(new_gr_dat, aes(x = x, y = line, colour = colour)) +
geom_point() +
coord_cartesian(xlim = c(process_starting_row-1*per_validation_period, max(new_gr_dat$x)))