如何遍历包含 ggplot2 代码的变量以将它们绘制在 R 中的同一张图上?
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))),
)
方法二是利用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 在很大程度上是一种函数式编程语言,因此通常认为 ill-advised 具有修改全局环境的函数(例如 timeStamp
)。取而代之的是 return 数据,以便用户可以分配 his/her 选择的符号 (myData <- timeStamp()
)。此外,在全局环境 'Date' 中调用变量也可能会造成混淆,因为这与基础名称 class 冲突。
我正在尝试使用 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))),
)
方法二是利用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 在很大程度上是一种函数式编程语言,因此通常认为 ill-advised 具有修改全局环境的函数(例如 timeStamp
)。取而代之的是 return 数据,以便用户可以分配 his/her 选择的符号 (myData <- timeStamp()
)。此外,在全局环境 'Date' 中调用变量也可能会造成混淆,因为这与基础名称 class 冲突。