如何将3D数据框架融合为长格式

时间:2017-12-13 15:24:24

标签: r

我有一个包含如下所示数据的文本文件:

#    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个级别。将它们全部绘制在一个图表中是没有用的。

1 个答案:

答案 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列(使用reshape2tidyr并使用构面分割您的可视化来获得您想要的内容。

首先拆分列:

dvt.separate <- data.vs.time.long %>% 
  separate(variable, into = c("pop", "nodes"), sep = '/')

使用variable列将此输出分为单独的popnodes变量:

> 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)

输出类似:

enter image description here

此外,您现在可以更轻松地过滤特定节点:

filter(dvt.separate, nodes == "node1") %>%
  ggplot(., aes(x = time, y = value, color = pop)) + 
  geom_line()

enter image description here

库:

library(dplyr)
library(tidyr)
library(ggplot2)