如何在 R 中绘制具有标准化 x 轴的多条线?
How to plot multiple lines with a normalised x axis in R?
distance1 grey1 distance2 grey2
1 0.0000000 -300.364 0.0000000 -135.219
2 0.2174741 -296.963 0.2114969 -132.601
3 0.4349482 -292.887 0.4229937 -131.959
4 0.6520882 -290.310 0.6341657 -133.514
5 0.8695623 -285.777 0.8456625 -127.111
6 1.0870364 -279.921 1.0571594 -116.404
7 1.3045105 -274.418 1.2686562 -116.850
8 1.5216505 -272.005 1.4798282 -115.464
9 1.7391246 -273.666 1.6913251 -102.823
10 1.9565987 -270.381 1.9028219 -101.497
11 2.1740728 -270.273 2.1143188 -98.245
12 2.3912128 -270.705 2.3254907 -98.474
我的 x 轴是我标准化为 0-100 的距离。我的 Y 轴是整个距离的强度值。我有 2 个样本,其中每个 Y 值都匹配一个特定的 X 值(注意样本 2 的行数比样本 1 多)。
我粘贴了前几行数据作为示例。如何在同一个图中绘制两个样本的图?之后如何创建 2 个样本的平均图?
不太清楚您要做什么,所以我将提供几个演示。首先,我假设您在这里有两个不同的数据集,第一个在第 1-2 列,第二个在第 3-4 列。这可以在ggplot2
中按字面意思完成:
library(ggplot2)
ggplot(dat) +
geom_line(aes(distance, grey1), color="red") +
geom_line(aes(distance1, grey2), color="blue")
但这种方法有点brute-forcing,并且会使诸如传说、color-control等之类的东西变得相当痛苦。我建议这个过程将受益于将数据重塑为 long-format,其中只有 x 和 y 变量加上一个来指示该行来自哪个组。例如,
library(data.table)
newdat <- data.table::melt(as.data.table(dat),
measure = patterns("^distance","^grey"),
value.name = c("distance", "grey"))
newdat
# variable distance grey
# <fctr> <num> <num>
# 1: 1 0.0000000 -300.364
# 2: 1 0.2174741 -296.963
# 3: 1 0.4349482 -292.887
# 4: 1 0.6520882 -290.310
# 5: 1 0.8695623 -285.777
# 6: 1 1.0870364 -279.921
# 7: 1 1.3045105 -274.418
# 8: 1 1.5216505 -272.005
# 9: 1 1.7391246 -273.666
# 10: 1 1.9565987 -270.381
# ---
# 15: 2 0.4229937 -131.959
# 16: 2 0.6341657 -133.514
# 17: 2 0.8456625 -127.111
# 18: 2 1.0571594 -116.404
# 19: 2 1.2686562 -116.850
# 20: 2 1.4798282 -115.464
# 21: 2 1.6913251 -102.823
# 22: 2 1.9028219 -101.497
# 23: 2 2.1143188 -98.245
# 24: 2 2.3254907 -98.474
新的 variable
列表示数据来自哪个 column-group。
这里,ggplot 中的绘图变得更简单一些:
ggplot(newdat, aes(distance, grey)) +
geom_line(aes(color = variable, group = variable))
请注意,我们现在有一个图例,它正在处理颜色本身。这些可以被覆盖,但这是一个不同的主题(并在此处的许多问题中解决)。
至于 “2 个样本的平均图”,这将在数据中包含更多上下文,目前 well-enough 未获悉。我最担心的是每组数据的 distance
和 grey
都没有完全对齐。也就是说,如果 distance
在两者中的值都正好是 1.000
,那么我认为我们可以安全地对这两个观察值的 grey
值进行平均。但是,一般情况并非如此(此样本数据集中的任何地方也不是)。
如果您真的想找到一种形式的平均值,我建议您将两条线插入到 distance
的已知域中并显示平均值。我会演示我的意思。
首先,我将添加点以便我们可以看到 x-wise 错位:
ggplot(newdat, aes(distance, grey, color = variable)) +
geom_line() +
geom_point()
现在,让我们汇总“平均值”(来自插值 distance
并将它们添加到原始 long-form 数据中。
newdist <- seq(0, min(max(dat$distance), max(dat$distance1)), by = 0.1)
newdat2 <- newdat[, setNames(approx(distance, grey, xout = newdist), c("distance", "grey")), by = variable
][, .(variable = "Avg", grey = mean(grey)), by = distance]
newdat2 <- rbindlist(list(newdat, newdat2), use.names = TRUE)
现在,我们可以使用 same plot 命令并得到第三行:
ggplot(newdat2, aes(distance, grey, color = variable)) +
geom_line() +
geom_point()
此方法正在对数据进行一些推论,我们在问题中没有太多的推论。我认为这是一个安全的步骤,但在盲目地对您的数据使用此技术之前,请确保它在统计上有意义。
数据(我在重命名列之前开始写这个,所以follow-on代码可能需要调整)。
dat <- structure(list(distance = c(0, 0.2174741, 0.4349482, 0.6520882, 0.8695623, 1.0870364, 1.3045105, 1.5216505, 1.7391246, 1.9565987, 2.1740728, 2.3912128), grey1 = c(-300.364, -296.963, -292.887, -290.31, -285.777, -279.921, -274.418, -272.005, -273.666, -270.381, -270.273, -270.705), distance1 = c(0, 0.2114969, 0.4229937, 0.6341657, 0.8456625, 1.0571594, 1.2686562, 1.4798282, 1.6913251, 1.9028219, 2.1143188, 2.3254907), grey2 = c(-135.219, -132.601, -131.959, -133.514, -127.111, -116.404, -116.85, -115.464, -102.823, -101.497, -98.245, -98.474)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
distance1 grey1 distance2 grey2
1 0.0000000 -300.364 0.0000000 -135.219
2 0.2174741 -296.963 0.2114969 -132.601
3 0.4349482 -292.887 0.4229937 -131.959
4 0.6520882 -290.310 0.6341657 -133.514
5 0.8695623 -285.777 0.8456625 -127.111
6 1.0870364 -279.921 1.0571594 -116.404
7 1.3045105 -274.418 1.2686562 -116.850
8 1.5216505 -272.005 1.4798282 -115.464
9 1.7391246 -273.666 1.6913251 -102.823
10 1.9565987 -270.381 1.9028219 -101.497
11 2.1740728 -270.273 2.1143188 -98.245
12 2.3912128 -270.705 2.3254907 -98.474
我的 x 轴是我标准化为 0-100 的距离。我的 Y 轴是整个距离的强度值。我有 2 个样本,其中每个 Y 值都匹配一个特定的 X 值(注意样本 2 的行数比样本 1 多)。 我粘贴了前几行数据作为示例。如何在同一个图中绘制两个样本的图?之后如何创建 2 个样本的平均图?
不太清楚您要做什么,所以我将提供几个演示。首先,我假设您在这里有两个不同的数据集,第一个在第 1-2 列,第二个在第 3-4 列。这可以在ggplot2
中按字面意思完成:
library(ggplot2)
ggplot(dat) +
geom_line(aes(distance, grey1), color="red") +
geom_line(aes(distance1, grey2), color="blue")
但这种方法有点brute-forcing,并且会使诸如传说、color-control等之类的东西变得相当痛苦。我建议这个过程将受益于将数据重塑为 long-format,其中只有 x 和 y 变量加上一个来指示该行来自哪个组。例如,
library(data.table)
newdat <- data.table::melt(as.data.table(dat),
measure = patterns("^distance","^grey"),
value.name = c("distance", "grey"))
newdat
# variable distance grey
# <fctr> <num> <num>
# 1: 1 0.0000000 -300.364
# 2: 1 0.2174741 -296.963
# 3: 1 0.4349482 -292.887
# 4: 1 0.6520882 -290.310
# 5: 1 0.8695623 -285.777
# 6: 1 1.0870364 -279.921
# 7: 1 1.3045105 -274.418
# 8: 1 1.5216505 -272.005
# 9: 1 1.7391246 -273.666
# 10: 1 1.9565987 -270.381
# ---
# 15: 2 0.4229937 -131.959
# 16: 2 0.6341657 -133.514
# 17: 2 0.8456625 -127.111
# 18: 2 1.0571594 -116.404
# 19: 2 1.2686562 -116.850
# 20: 2 1.4798282 -115.464
# 21: 2 1.6913251 -102.823
# 22: 2 1.9028219 -101.497
# 23: 2 2.1143188 -98.245
# 24: 2 2.3254907 -98.474
新的 variable
列表示数据来自哪个 column-group。
这里,ggplot 中的绘图变得更简单一些:
ggplot(newdat, aes(distance, grey)) +
geom_line(aes(color = variable, group = variable))
请注意,我们现在有一个图例,它正在处理颜色本身。这些可以被覆盖,但这是一个不同的主题(并在此处的许多问题中解决)。
至于 “2 个样本的平均图”,这将在数据中包含更多上下文,目前 well-enough 未获悉。我最担心的是每组数据的 distance
和 grey
都没有完全对齐。也就是说,如果 distance
在两者中的值都正好是 1.000
,那么我认为我们可以安全地对这两个观察值的 grey
值进行平均。但是,一般情况并非如此(此样本数据集中的任何地方也不是)。
如果您真的想找到一种形式的平均值,我建议您将两条线插入到 distance
的已知域中并显示平均值。我会演示我的意思。
首先,我将添加点以便我们可以看到 x-wise 错位:
ggplot(newdat, aes(distance, grey, color = variable)) +
geom_line() +
geom_point()
现在,让我们汇总“平均值”(来自插值 distance
并将它们添加到原始 long-form 数据中。
newdist <- seq(0, min(max(dat$distance), max(dat$distance1)), by = 0.1)
newdat2 <- newdat[, setNames(approx(distance, grey, xout = newdist), c("distance", "grey")), by = variable
][, .(variable = "Avg", grey = mean(grey)), by = distance]
newdat2 <- rbindlist(list(newdat, newdat2), use.names = TRUE)
现在,我们可以使用 same plot 命令并得到第三行:
ggplot(newdat2, aes(distance, grey, color = variable)) +
geom_line() +
geom_point()
此方法正在对数据进行一些推论,我们在问题中没有太多的推论。我认为这是一个安全的步骤,但在盲目地对您的数据使用此技术之前,请确保它在统计上有意义。
数据(我在重命名列之前开始写这个,所以follow-on代码可能需要调整)。
dat <- structure(list(distance = c(0, 0.2174741, 0.4349482, 0.6520882, 0.8695623, 1.0870364, 1.3045105, 1.5216505, 1.7391246, 1.9565987, 2.1740728, 2.3912128), grey1 = c(-300.364, -296.963, -292.887, -290.31, -285.777, -279.921, -274.418, -272.005, -273.666, -270.381, -270.273, -270.705), distance1 = c(0, 0.2114969, 0.4229937, 0.6341657, 0.8456625, 1.0571594, 1.2686562, 1.4798282, 1.6913251, 1.9028219, 2.1143188, 2.3254907), grey2 = c(-135.219, -132.601, -131.959, -133.514, -127.111, -116.404, -116.85, -115.464, -102.823, -101.497, -98.245, -98.474)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))