[英]How can I loop through variables containing ggplot2 code to plot them on the same graph in R?
我正在尝试使用 for 循环在 R 中的一个 ggplot 中绘制多行。 目前,我不相信我可以使用 Melt() 命令将我的数据转换为长格式,因为我计划在未来添加到图形中的一些附加功能(过滤器、用户输入等在闪亮的仪表板中 -这将是我的第一个仪表板,所以如果我不正确,请告诉我)。 我目前设置了以下代码(见下文)以将 geom_line() 命令分配给动态变量(产生 x1 和 x2)。 接下来,我生成一个与创建的动态变量相关联的字符串向量。 变量 m 被分配为我的 ggplot() 命令。 如何使用字符串向量调用 x# 变量来创建等效于 m + x1 + x2 + scale_color_manual("red", "green") 的绘图? 请注意,这是针对 QC 过程的,需要在各种图表中绘制 200 多个变量,因此该解决方案需要具有可扩展性,并且不需要我明确输入每个 x# 变量。
# Create mock data - need to run the timeStamp() function on it's own first
timeStamp <- function(){
start <- readline("Enter Start Date (YYYY-MM-DD): ")
end <- readline("Enter End Date (YYYY-MM-DD): ")
start <- as.POSIXct(start)
end <- as.POSIXct(end)
end <- end + as.difftime(1, unit = "days")
interval <- 60
Date <- seq(from=start, by = interval*60, to=end)
Date <- as.data.frame(Date)
n <- nrow(Date)
Date <- Date[-1, ]
Date <- as.data.frame(Date)
assign("Date", Date, envir = .GlobalEnv)
}
timeStamp()
# Run timestamp function for any leap year use format 2028-01-01 to 2028-12-31 as inputs
# Creates remaining mock data
mock1 <- rep(c(1), times = 87840)
mock2 <- rep(c(2), times = 87840)
mock3 <- runif(87840, min=-100, max=100)
mock4 <- runif(87840, min=-10, max=10)
mock5 <- runif(87840, min=-150, max=150)
newDate <- rbind(Date, Date, Date, Date, Date,
Date, Date, Date, Date, Date)
# Inputs to for loop
dataFinal <- as.data.frame(cbind(newDate, mock1, mock2, mock5, mock4, mock3))
name <- list(names(dataFinal))
price <- names(dataFinal[ ,c(4,6)])
m <- ggplot(dataFinal)
for (i in seq_along(price)) {
dynamVar <- paste0("x", i)
dynamCol <- paste0("col", i)
assign(dynamVar, geom_line(aes_string(x = "Date", y = price[i], colour = as.factor(assign(dynamCol, price[i])))))
}
xPlot <- sprintf("x%s",seq(1:length(price)))
# This line of code produces a mock graphic that I am wanting to recreate, but instead of specifying x1 and x2, I want to produce the graph dynamically
m+x1+x2+scale_colour_manual(values=c("red", "green"))
有两种方法可以解决这个问题。 首先是加法方式,这和你问的问题最直接相关。 我会使用purrr::reduce
而不是for
循环
purrr::reduce(
price, .init = m,
~ .x + geom_line(aes_string(x = "Date", y = .y, color = as.factor(.y))),
)
方法 2 是使用geom_line
的组美学。 您只需要先对数据进行透视。
dataFinal %>%
dplyr::select(c(1,4,6)) %>%
dplyr::sample_n(1e3) %>%
tidyr::pivot_longer(-Date) %>%
ggplot(aes(x = Date, y = value)) +
geom_line(aes(group = name, colour = as.factor(name)))
我对数据进行了采样,因为否则mock5
屏蔽mock3
(即使它被绘制)
附带说明一下,由于 R 主要是一种函数式编程语言,通常认为让函数(例如timeStamp
)修改全局环境是timeStamp
。 而是让它返回数据,以便用户可以分配他/她选择的符号( myData <- timeStamp()
)。 此外,在全局环境“Date”中调用变量也可能会造成混淆,因为这与基类的名称相冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.