为什么 R 在解析绘图参数时表现不同?
Why does R behave differently when parsing parameters of plotting?
我正在尝试使用 ggplot 在单个折线图上绘制多个时间序列变量。我正在使用 data.frame ,其中包含 n 个时间序列变量和一列时间段。本质上,我想遍历 data.frame,并将 n goem_lines 添加到单个图表。
最初我尝试使用以下代码,其中;
- df = data.frame包含n个时间序列变量,1列时间段
- wid = n(时间序列变量的个数)
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
for (i in 1:wid) {
p <- p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
}
ggplotly(p)
但是,这只会生成 data.frame 中最终时间序列变量的图。然后我进一步调查,发现以下几组代码产生完全不同的结果:
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
i = 1
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 2
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 3
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
ggplotly(p)
Plot produced by code above
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
p = p + geom_line(aes(x=df$Time, y=df[,1], color=var.lab[1]))
p = p + geom_line(aes(x=df$Time, y=df[,2], color=var.lab[2]))
p = p + geom_line(aes(x=df$Time, y=df[,3], color=var.lab[3]))
ggplotly(p)
Plot produced by code above
在我看来,这两套代码是相同的,所以谁能解释为什么它们会产生如此不同的结果?
我知道这可能使用自动绘图很容易完成,但我对这两个代码片段的行为更感兴趣。
你想要做的是 'hack' 绘制多条线的方法,但它在 ggplot 术语中并不理想。为了成功,我会使用 aes_string
。但这是一个 hack.
df <- data.frame(Time = 1:20,
Var1 = rnorm(20),
Var2 = rnorm(20, mean = 0.5),
Var3 = rnorm(20, mean = 0.8))
vars <- paste0("Var", 1:3)
col_vec <- RColorBrewer::brewer.pal(3, "Accent")
library(ggplot2)
p <- ggplot(df, aes(Time))
for (i in 1:length(vars)) {
p <- p + geom_line(aes_string(y = vars[i]), color = col_vec[i], lwd = 1)
}
p + labs(y = "value")
如何正确操作
为了更恰当地绘制此图,您需要先旋转数据,以便将每个美学 (aes) 映射到数据框中的一个变量。这意味着我们的数据框中需要一个变量 color
。因此,我们 pivot_longer
并再次绘制:
library(tidyr)
df_melt <- pivot_longer(df, cols = Var1:Var3, names_to = "var")
ggplot(df_melt, aes(Time, value, color = var)) +
geom_line(lwd = 1) +
scale_color_manual(values = col_vec)
我正在尝试使用 ggplot 在单个折线图上绘制多个时间序列变量。我正在使用 data.frame ,其中包含 n 个时间序列变量和一列时间段。本质上,我想遍历 data.frame,并将 n goem_lines 添加到单个图表。
最初我尝试使用以下代码,其中;
- df = data.frame包含n个时间序列变量,1列时间段
- wid = n(时间序列变量的个数)
p <- ggplot() + scale_color_manual(values=c(colours[1:wid])) for (i in 1:wid) { p <- p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i])) } ggplotly(p)
但是,这只会生成 data.frame 中最终时间序列变量的图。然后我进一步调查,发现以下几组代码产生完全不同的结果:
p <- ggplot() + scale_color_manual(values=c(colours[1:wid])) i = 1 p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i])) i = 2 p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i])) i = 3 p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i])) ggplotly(p)
Plot produced by code above
p <- ggplot() + scale_color_manual(values=c(colours[1:wid])) p = p + geom_line(aes(x=df$Time, y=df[,1], color=var.lab[1])) p = p + geom_line(aes(x=df$Time, y=df[,2], color=var.lab[2])) p = p + geom_line(aes(x=df$Time, y=df[,3], color=var.lab[3])) ggplotly(p)
Plot produced by code above
在我看来,这两套代码是相同的,所以谁能解释为什么它们会产生如此不同的结果?
我知道这可能使用自动绘图很容易完成,但我对这两个代码片段的行为更感兴趣。
你想要做的是 'hack' 绘制多条线的方法,但它在 ggplot 术语中并不理想。为了成功,我会使用 aes_string
。但这是一个 hack.
df <- data.frame(Time = 1:20,
Var1 = rnorm(20),
Var2 = rnorm(20, mean = 0.5),
Var3 = rnorm(20, mean = 0.8))
vars <- paste0("Var", 1:3)
col_vec <- RColorBrewer::brewer.pal(3, "Accent")
library(ggplot2)
p <- ggplot(df, aes(Time))
for (i in 1:length(vars)) {
p <- p + geom_line(aes_string(y = vars[i]), color = col_vec[i], lwd = 1)
}
p + labs(y = "value")
如何正确操作
为了更恰当地绘制此图,您需要先旋转数据,以便将每个美学 (aes) 映射到数据框中的一个变量。这意味着我们的数据框中需要一个变量 color
。因此,我们 pivot_longer
并再次绘制:
library(tidyr)
df_melt <- pivot_longer(df, cols = Var1:Var3, names_to = "var")
ggplot(df_melt, aes(Time, value, color = var)) +
geom_line(lwd = 1) +
scale_color_manual(values = col_vec)