【问题标题】:Plotting a series of data in R在 R 中绘制一系列数据
【发布时间】:2016-09-10 22:25:12
【问题描述】:

我有一个包含以下几行的 CSV 文件:

10,130,A,100,1000
10,130,B,200,-200
10,130,C,300,1200
20,140,A,120,1050
20,140,B,220,-300
20,140,C,320,1250
30,120,A,145,1130
30,120,B,255,1000
30,120,C,355,1110
...

以此类推,在第一列中,每增加三行,10。对于第 3 列中的每种类型(A、B 和 C),每行在第 4 列和第 5 列中包含两个值。对于每组三行,第 1 列和第 2 列中的值是相同的。

我是这样读的:

data <- read.csv("data_out.csv", header=FALSE, sep=",")

从文件中读取的每三行包含 8 个值,可以在图表上绘制为 Y(前三行的示例):

  1. 第 1 列 (10) 中的值
  2. 第 2 列中的值 (130)
  3. 类型 A (100) 的第 4 列中的值
  4. 类型 A (1000) 的第 5 列中的值
  5. 类型 B (200) 的第 4 列中的值
  6. 类型 B (-200) 的第 5 列中的值
  7. 类型 C (300) 的第 4 列中的值
  8. 类型 C (1200) 的第 5 列中的值

它们将被绘制为 X = 10。

所以前 8 个点将具有以下坐标 (X,Y):

(10,10); (10,130); (10,100); (10,1000); (10,200); (10,-200); (10,300); (10,1200)

第 1 列中 20 的下三行将具有坐标:

(20,20); (20,140); (20,120); (20,1050); (20,220); (20,-300); (20,320); (20,1250)

对于输入文件中的第三行和任何其他三行的集合也是如此。

应连接代表每组三条线中的这 8 个值中的每一个的点以形成折线图 similar to this one(但有 8 个折线图,而不是示例中的 4 个)。所以在同一个图表上会有 8 个折线图,分别代表 X=10、X=20、X=30 等的值。

关于解决方案的问题

我知道如何绘制一条线,例如plot(data[,1],data[,4],type="l") 但是如何绘制多条线?

以及如何确保 Y 的 0 在正确的位置,以便 C5 的负值也可以正确绘制?

另外,我知道有 aggregate 函数可用于按类型(A、B、C)分组,但我不想执行任何汇总或平均,所以我可能正在寻找过滤器(按类型)而不是聚合?

我可能还想确保 C1 中的不同值的数量与 C2 中的相同(纯粹是为了验证输入数据是否正确)。

【问题讨论】:

  • 您的图表应该是什么样的?能举个例子吗?
  • 我真的试过了,但我不明白你要求什么样的情节。您对如何重新格式化数据的解释也令人困惑。
  • 如果我能得到关于解决方案问题的答案,我应该能够弄清楚其余的问题。该图非常简单,看起来像这样:jpgraph.net/images/howto/mulyaxisex1.png 但这个只显示 4 条线(或图,我不熟悉术语),我的在同一张图上有 8 条线。也许三个 Y 刻度是个好主意,一个用于 C1/C2 值,一个用于 C4,一个用于 C5 值。
  • 另外,刚刚添加了一个编辑。
  • 你的问题还不清楚。首先,您应该重新安排您的 df,使每个点 (x1,y1) 的坐标位于同一行中,而我在您的数据中找不到。这使得我们无法理解哪些值应该得到一分。然后在第一行使用plot(...,type="l") 和添加以下行使用lines(...) 轻松绘图可能是解决方案。

标签: r graph aggregate grouping aggregation


【解决方案1】:

鉴于您已添加到编辑中的数据,我将再次解决您的问题2。希望您能在此解释后解决您的实际问题。

您说您从 csv 读取的数据框:

df = data.frame(
  c(10,130,"A",100,1000),
  c(10,130,"B",200,-200),
  c(10,130,"C",300,1200),
  c(20,140,"A",120,1050),
  c(20,140,"B",220,-300),
  c(20,140,"C",320,1250),
  c(30,120,"A",145,1130),
  c(30,120,"B",255,1000),
  c(30,120,"C",355,1110))

我们需要将其转置为列格式,您最初在帖子中提到过。

df = data.frame(t(df))

我根据您的示例命名该列:

names(df) = c("C1","C2","C3","C4","C5")

在 R 中安装和读取包:

install.packages("reshape2")
install.packages("ggplot2")
library(reshape2)
library(ggplot2)

melt 将您的数据重塑为有助于绘制图表的长格式。第一个变量 C4C5 被转换为长格式,并重命名以在图中识别它们。

d1 = melt(df[,c(1,3:5)], id.vars = c("C1","C3"), measure.vars = c("C4","C5"), variable.name = "col")
d1$group = paste0(d1$C3,d1$col)

然后变量C1C2在没有[A,B,C]的情况下被融化。

d2 = unique(melt(df[,c(1:2)], id.vars = "C1", measure.vars = c("C1","C2"), variable.name = "group"))

两个融合的数据集由绘图所需的列组合。

p = rbind(d1[,c("C1","group","value")], d2[,c("C1","group","value")])
p$value = as.numeric(p$value)

您可以绘制线条,按您创建的组为线条着色以识别它们,然后绘制标签以读取值。

ggplot(p, aes(x=C1, y=value, group=group, color=group, label=value)) + 
  geom_line() + geom_point() + geom_text(aes(label=value, hjust= 1, vjust=-1))

【讨论】:

  • 谢谢,我很欣赏你的看法,但输入数据并不完全是我所拥有的。我使用从 csv 读取的示例数据和应该绘制的确切输出再次添加了编辑。您的图表可能是正确的,但如果不解释代码中的每个转换是做什么的,我将无法修复它以处理我读取的数据。
  • 您编辑的df 有 9 列和 5 行。这种格式正确吗?同样,您的解释与格式不符。
  • 这是 csv 文件中的一行:10,130,A,100,1000,而不是一列。文件中有 300 行这样的行。对于每三行,图表上将有 8 个点。也许我没有正确使用术语?
  • 我就是这么想的。只需从上面的代码中删除这行df = data.frame(t(df)),它应该可以工作。
  • 另外,以后请在提问之前阅读how to of reproducible example。对于您当前的问题,花一些时间了解每个脚本的作用。这是一个相当简单的问题,在帮助代码之后解决它应该没有任何困难。
猜你喜欢
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 2020-10-25
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
相关资源
最近更新 更多