我有一个包含如下所示数据的文本文件:
# time; allPop; allPop; allPop; ions1; ions1; ions1; elec1; elec1; elec1;
# ; allNodes; node0; node1; allNodes; node0; node1; allNodes; node0; node1;
0.011082077;-330.84293;-5.28E-04;-0.008617032;2.39E-12;9.94E-13;1.29E-12;-331.09302;-0.015284455;-0.013646739;
0.011132077;-332.19788;1.17E-04;-0.004885694;2.76E-12;9.99E-13;1.30E-12;-332.44925;-0.014786674;-0.009936244;
0.011182077;-330.7951;2.05E-04;-0.003262551;3.10E-12;9.98E-13;1.27E-12;-331.0478;-0.015050205;-0.00879398;
0.011232077;-331.62976;0.001411756;-0.001674229;3.35E-12;9.85E-13;1.28E-12;-331.88593;-0.015500192;-0.008433639;
0.011282077;-333.03204;-8.67E-04;-0.001743055;3.54E-12;9.81E-13;1.29E-12;-333.28497;-0.01616466;-0.009426347;
0.011332078;-330.76794;-0.001515289;-0.001287116;3.66E-12;9.86E-13;1.31E-12;-331.01965;-0.015228378;-0.008569364;
0.011382078;-331.39044;0.002540908;-5.25E-04;3.71E-12;9.92E-13;1.32E-12;-331.6468;-0.014409032;-0.008052639;
0.011432078;-330.43414;-0.001792867;-2.51E-04;3.68E-12;9.60E-13;1.32E-12;-330.68936;-0.01623829;-0.008444168;
0.011482078;-330.86917;4.81E-04;1.41E-04;3.70E-12;9.76E-13;1.33E-12;-331.12268;-0.014885588;-0.009113268;
0.011532078;-330.33435;6.66E-04;-1.58E-04;3.72E-12;9.79E-13;1.33E-12;-330.58813;-0.015093705;-0.009414361;
0.011582078;-330.7523;-7.40E-04;-0.001010344;3.70E-12;9.66E-13;1.32E-12;-331.00278;-0.015855879;-0.009049743;
0.011632077;-329.58597;2.41E-04;-1.02E-04;3.71E-12;9.67E-13;1.32E-12;-329.83893;-0.015224142;-0.008584219;
0.011682077;-331.54898;-0.001295898;0.001874733;3.71E-12;9.69E-13;1.31E-12;-331.80432;-0.015666598;-0.008926244;
因此,作为时间的函数,我有不同的群体与不同的节点相关联。 allPop是给定节点上所有种群的总和,而allNodes是所有节点上给定种群的总和。
为了便于阅读,上面的文件被截断,这解释了为什么在这个例子中总和不匹配。
现在,我需要将这些数据以长格式存储在数据框中,以便能够使用ggplot2轻松绘制它。
读取两行标题可以通过以下方式完成:
header <- readLines(text.connection, n = 2)
header <- gsub("#", "", header)
header <- gsub(" ", "", header)
header <- strsplit(header, ",")
可以使用以下方式读取数据:
data.vs.time <- read.csv(text.connection, header = FALSE, skip = 2)
现在我想做的是以长格式融合(从reshape2)这个数据框。
我的第一个想法如下:
colnames(data.vs.time) <- paste(header[[1]], header[[2]], sep = "/")
colnames(data.vs.time)[[1]] <- "time"
data.vs.time.molten <- melt(data.vs.time, id.vars = "time")
这给了我类似的东西:
time variable value
1 0.01000000 allPop/allNodes -2.927736e-13
2 0.01000000 allPop/allNodes -6.097465e+02
3 0.01000000 allPop/allNodes -5.440071e+02
4 0.01000000 allPop/allNodes -5.120425e+02
5 0.01000000 allPop/allNodes -4.633145e+02
6 0.01000000 allPop/allNodes -4.168849e+02
[...]
好吧,我可以用它来绘制:
ggplot(data.vs.time.molten, aes(time, value, color = variable)) + geom_line()
它有效,但它不是真的可读。曲线太多,颜色不足。
如果我只想在一个节点或一个人群中显示数据,我必须做以下事情:
ggplot(data.vs.time.molten[grepl("node0", as.character(data.vs.time.molten$variable)), ], aes(time, value, color = variable)) + geom_line()
但传说是多余的。
有更好的方法吗?
我在考虑获取一个包含4列的数据框:时间,节点,弹出,值,但不知道如何使用它。
是否有一个很好的解决方案以可读的方式绘制曲线?在现实生活中,我对“变量”列有36个级别。将它们全部绘制在一个图表中是没有用的。
答案 0 :(得分:1)
我按照您的示例数据执行了步骤,并且我有一个包含117行的数据框,如下所示:
> head(data.vs.time.long)
time variable value
1 0.01108208 allPop/allNodes -330.8429
2 0.01113208 allPop/allNodes -332.1979
3 0.01118208 allPop/allNodes -330.7951
4 0.01123208 allPop/allNodes -331.6298
5 0.01128208 allPop/allNodes -333.0320
也许您可以通过拆分variable
列(使用reshape2
或tidyr
并使用构面分割您的可视化来获得您想要的内容。
首先拆分列:
dvt.separate <- data.vs.time.long %>%
separate(variable, into = c("pop", "nodes"), sep = '/')
使用variable
列将此输出分为单独的pop
和nodes
变量:
> head(dvt.separate)
time pop nodes value
1 0.01108208 allPop allNodes -330.8429
2 0.01113208 allPop allNodes -332.1979
3 0.01118208 allPop allNodes -330.7951
4 0.01123208 allPop allNodes -331.6298
5 0.01128208 allPop allNodes -333.0320
然后,用facet_wrap
绘图(注意我已经记录了绝对值的日志以表明情节正在发挥作用):
ggplot(dvt.separate,
aes(x = time, y = log(abs(value)))) +
geom_line(aes(color = nodes)) +
facet_wrap(facets = ~ pop)
输出类似:
此外,您现在可以更轻松地过滤特定节点:
filter(dvt.separate, nodes == "node1") %>%
ggplot(., aes(x = time, y = value, color = pop)) +
geom_line()
库:
library(dplyr)
library(tidyr)
library(ggplot2)