在 R 中创建带有两个 Y 轴的分组条形图
Creating a grouped barplot with two Y axes in R
我有以下数据框,其中包含 8 周时间跨度的视觉/每小时目击次数 (SPH) 和声学/每小时点击次数 (CPH) 数据集。我想要一个分组条形图,将一周内的两个值分组在一起。所以例如第 1 周为 2.676 sightings/h,第 1 周为 75.35 clicks/h。由于两个变量的单位不同,我还需要两个 y 轴,一个用于左侧的 sightings/h,另一个用于clicks/h右边。
data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8), SPH = c(2.676, 2.660, 4.175, 2.134,
3.742, 1.395, 4.739, 2.756), CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
我试图创建一个矩阵来绘制数据,但我不知道如何正确地告诉 R 前两个变量属于第 1 周,后两个变量属于第 2 周等。
希望大家能帮帮我。
提前致以最诚挚的问候和感谢。 :)
这个怎么样:
dat <- data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8),
SPH = c(2.676, 2.660, 4.175, 2.134, 3.742, 1.395, 4.739, 2.756),
CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
library(tidyr)
library(dplyr)
## Find minimum and maximum values for each variable
tmp <- dat %>%
summarise(across(c("SPH", "CPH"), ~list(min = min(.x), max=max(.x)))) %>%
unnest(everything())
## make mapping from CPH to SPH
m <- lm(SPH ~ CPH, data=tmp)
## make mapping from SPH to CPH
m_inv <- lm(CPH ~ SPH, data=tmp)
## transform CPH so it's on the same scale as SPH.
## to do this, you need to use the coefficients from model m above
dat <- dat %>%
mutate(CPH = coef(m)[1] + coef(m)[2]*CPH) %>%
## pivot the data so all plotting values are in a single column
pivot_longer(c("SPH", "CPH"),
names_to="var", values_to="vals") %>%
mutate(var = factor(var, levels=c("SPH", "CPH"),
labels=c("Sightings", "Clicks")))
ggplot(dat, aes(x=as.factor(Week), y=vals, fill=var)) +
geom_bar(position="dodge", stat="identity") +
## use model m_inv from above to identify the transformation from the tick values of SPH
## to the appropriate tick values of CPH
scale_y_continuous(sec.axis=sec_axis(trans = ~coef(m_inv)[1] + coef(m_inv)[2]*.x, name="Clicks/hour")) +
labs(y="Sightings/hour", x="Week", fill="") +
theme_bw() +
theme(legend.position="top")
更新 - 两个轴都从零开始
要使两个轴都从零开始,您需要更改线性图中使用的值都从零开始。这是一个更新的完整示例:
dat <- data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8),
SPH = c(2.676, 2.660, 4.175, 2.134, 3.742, 1.395, 4.739, 2.756),
CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
library(tidyr)
library(dplyr)
## Find minimum and maximum values for each variable
tmp <- dat %>%
summarise(across(c("SPH", "CPH"), ~list(min = min(.x), max=max(.x)))) %>%
unnest(everything())
## set lower bound of each to zero
tmp$SPH[1] <- 0
tmp$CPH[1] <- 0
## make mapping from CPH to SPH
m <- lm(SPH ~ CPH, data=tmp)
## make mapping from SPH to CPH
m_inv <- lm(CPH ~ SPH, data=tmp)
## transform CPH so it's on the same scale as SPH.
## to do this, you need to use the coefficients from model m above
dat <- dat %>%
mutate(CPH = coef(m)[1] + coef(m)[2]*CPH) %>%
## pivot the data so all plotting values are in a single column
pivot_longer(c("SPH", "CPH"),
names_to="var", values_to="vals") %>%
mutate(var = factor(var, levels=c("SPH", "CPH"),
labels=c("Sightings", "Clicks")))
ggplot(dat, aes(x=as.factor(Week), y=vals, fill=var)) +
geom_bar(position="dodge", stat="identity") +
## use model m_inv from above to identify the transformation from the tick values of SPH
## to the appropriate tick values of CPH
scale_y_continuous(sec.axis=sec_axis(trans = ~coef(m_inv)[1] + coef(m_inv)[2]*.x, name="Clicks/hour")) +
labs(y="Sightings/hour", x="Week", fill="") +
theme_bw() +
theme(legend.position="top")
我有以下数据框,其中包含 8 周时间跨度的视觉/每小时目击次数 (SPH) 和声学/每小时点击次数 (CPH) 数据集。我想要一个分组条形图,将一周内的两个值分组在一起。所以例如第 1 周为 2.676 sightings/h,第 1 周为 75.35 clicks/h。由于两个变量的单位不同,我还需要两个 y 轴,一个用于左侧的 sightings/h,另一个用于clicks/h右边。
data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8), SPH = c(2.676, 2.660, 4.175, 2.134,
3.742, 1.395, 4.739, 2.756), CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
我试图创建一个矩阵来绘制数据,但我不知道如何正确地告诉 R 前两个变量属于第 1 周,后两个变量属于第 2 周等。
希望大家能帮帮我。
提前致以最诚挚的问候和感谢。 :)
这个怎么样:
dat <- data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8),
SPH = c(2.676, 2.660, 4.175, 2.134, 3.742, 1.395, 4.739, 2.756),
CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
library(tidyr)
library(dplyr)
## Find minimum and maximum values for each variable
tmp <- dat %>%
summarise(across(c("SPH", "CPH"), ~list(min = min(.x), max=max(.x)))) %>%
unnest(everything())
## make mapping from CPH to SPH
m <- lm(SPH ~ CPH, data=tmp)
## make mapping from SPH to CPH
m_inv <- lm(CPH ~ SPH, data=tmp)
## transform CPH so it's on the same scale as SPH.
## to do this, you need to use the coefficients from model m above
dat <- dat %>%
mutate(CPH = coef(m)[1] + coef(m)[2]*CPH) %>%
## pivot the data so all plotting values are in a single column
pivot_longer(c("SPH", "CPH"),
names_to="var", values_to="vals") %>%
mutate(var = factor(var, levels=c("SPH", "CPH"),
labels=c("Sightings", "Clicks")))
ggplot(dat, aes(x=as.factor(Week), y=vals, fill=var)) +
geom_bar(position="dodge", stat="identity") +
## use model m_inv from above to identify the transformation from the tick values of SPH
## to the appropriate tick values of CPH
scale_y_continuous(sec.axis=sec_axis(trans = ~coef(m_inv)[1] + coef(m_inv)[2]*.x, name="Clicks/hour")) +
labs(y="Sightings/hour", x="Week", fill="") +
theme_bw() +
theme(legend.position="top")
更新 - 两个轴都从零开始
要使两个轴都从零开始,您需要更改线性图中使用的值都从零开始。这是一个更新的完整示例:
dat <- data.frame(Week = c(1, 2, 3, 4, 5, 6, 7, 8),
SPH = c(2.676, 2.660, 4.175, 2.134, 3.742, 1.395, 4.739, 2.756),
CPH = c(75.35, 29.58, 20.51, 80.43, 97.94, 85.39, 168.61, 142.19))
library(tidyr)
library(dplyr)
## Find minimum and maximum values for each variable
tmp <- dat %>%
summarise(across(c("SPH", "CPH"), ~list(min = min(.x), max=max(.x)))) %>%
unnest(everything())
## set lower bound of each to zero
tmp$SPH[1] <- 0
tmp$CPH[1] <- 0
## make mapping from CPH to SPH
m <- lm(SPH ~ CPH, data=tmp)
## make mapping from SPH to CPH
m_inv <- lm(CPH ~ SPH, data=tmp)
## transform CPH so it's on the same scale as SPH.
## to do this, you need to use the coefficients from model m above
dat <- dat %>%
mutate(CPH = coef(m)[1] + coef(m)[2]*CPH) %>%
## pivot the data so all plotting values are in a single column
pivot_longer(c("SPH", "CPH"),
names_to="var", values_to="vals") %>%
mutate(var = factor(var, levels=c("SPH", "CPH"),
labels=c("Sightings", "Clicks")))
ggplot(dat, aes(x=as.factor(Week), y=vals, fill=var)) +
geom_bar(position="dodge", stat="identity") +
## use model m_inv from above to identify the transformation from the tick values of SPH
## to the appropriate tick values of CPH
scale_y_continuous(sec.axis=sec_axis(trans = ~coef(m_inv)[1] + coef(m_inv)[2]*.x, name="Clicks/hour")) +
labs(y="Sightings/hour", x="Week", fill="") +
theme_bw() +
theme(legend.position="top")