Rob*_*att 29 r graph gnuplot flat-file rrdtool
我在flatfile中收集一些系统数据,其格式如下:
YYYY-MM-DD-HH24:MI:SS DD1 DD2 DD3 DD4
Run Code Online (Sandbox Code Playgroud)
其中DD1-DD4是四项数据.该文件的一个示例是:
2011-02-01-13:29:53 16 8 7 68
2011-02-01-13:29:58 13 8 6 110
2011-02-01-13:30:03 26 25 1 109
2011-02-01-13:30:08 13 12 1 31
2011-02-01-13:30:14 192 170 22 34
2011-02-01-13:30:19 16 16 0 10
2011-02-01-13:30:24 137 61 76 9
2011-02-01-13:30:29 452 167 286 42
2011-02-01-13:30:34 471 177 295 11
2011-02-01-13:30:39 502 192 309 10
Run Code Online (Sandbox Code Playgroud)
该文件超过200万行,每五秒钟有一个数据点.
我需要绘制这些数据,以便能够从中获得意义.
我试过的
目前我已尝试使用各种unix工具gnuplot和rrdtool(awk,sed等).这两种方法都有效,但每次我想以不同的方式查看数据时,似乎都需要大量的切割和重新编辑数据.我的直觉是rrdtool是正确的方法,但目前我正在努力将数据快速地加入其中,部分原因是因为我必须将我的时间戳转换为Unix时代.我的理解是,如果我决定我想要一个新的聚合粒度,我必须重建rrd(这对于实时收集是有意义的,但不是像这样的追溯加载).这些事情让我觉得我可能正在使用错误的工具.
将数据收集到平面文件是固定的 - 例如,我无法将集合直接传递到rrdtool.
我的问题
我希望人们对制图的最佳方式有所了解.我有这些要求:
有什么建议?
JD *_*ong 26
这是一个非常好的问题.我很高兴看到一些R人在努力.我也认为R是适合这项工作的工具,虽然它是我的主要锤子,所以一切看起来都像是钉子给我.
解决这一挑战需要一些R概念.在我看来,你需要以下(parens参考):
这是使用2mm点的示例代码.如果您注意到,我没有说明绘制所有2mm点.它很慢而且不那么有用.但这应该会给你一些入门的想法.如果您决定跳下R兔子洞,请随时回来提出更具体的问题!
require( xts )
require( lubridate )
## set up some example data
dataLength <- 2e6
startTime <- ymd_hms("2011-02-01-13-29-53")
fistFullOfSeconds <- 1:dataLength
date <- startTime + fistFullOfSeconds
DD1 <- rnorm( dataLength )
DD2 <- DD1 + rnorm(dataLength, 0, .1 )
DD3 <- rnorm( dataLength, 10, 2)
DD4 <- rnorm( dataLength )
myXts <- xts(matrix( c( DD1, DD2, DD3, DD4 ), ncol=4 ), date)
## now all the data are in the myXts object so let's do some
## summarizing and visualization
## grabbing just a single day from the data
## converted to data.frame to illustrate default data frame plotting
oneDay <- data.frame( myXts["2011-02-02"] )
plot( oneDay )
Run Code Online (Sandbox Code Playgroud)
DD1和DD2之间的关系有点跳出来
boxplot( oneDay )
Run Code Online (Sandbox Code Playgroud)
Boxplot是统计图形的饼图.你喜欢讨厌的情节.当我们在这里时,可能会链接到此.
## look at the max value of each variable every minute
par(mfrow=c(4,1)) ## partitions the graph window
ep <- endpoints(myXts,'minutes')
plot(period.apply(myXts[,1],INDEX=ep,FUN=max))
plot(period.apply(myXts[,2],INDEX=ep,FUN=max))
plot(period.apply(myXts[,3],INDEX=ep,FUN=max))
plot(period.apply(myXts[,4],INDEX=ep,FUN=max))
Run Code Online (Sandbox Code Playgroud)
即使在一分钟的分辨率下,我也不确定这是否有用.应该是子集.
这里有一些R代码可以在4列2000000行中使用8000000个数字:
> d=matrix(runif(8000000),ncol=4)
> dim(d)
[1] 2000000 4
> plot(d[1:1000,1])
> plot(d[1:1000,1],type='l')
> plot(d[1:10000,1],type='l')
Run Code Online (Sandbox Code Playgroud)
现在它开始有点慢:
> plot(d[1:100000,1],type='l')
Run Code Online (Sandbox Code Playgroud)
那两列的相关性如何:
> cor(d[,1],d[,2])
[1] 0.001708502
Run Code Online (Sandbox Code Playgroud)
- 瞬间.傅里叶变换?
> f=fft(d[,1])
Run Code Online (Sandbox Code Playgroud)
也是即时的.不要尝试绘制它.
让我们绘制其中一列的精简版本:
> plot(d[seq(1,2000000,len=1000),1],type='l')
Run Code Online (Sandbox Code Playgroud)
- 瞬间.
真正缺少的是一个交互式绘图,您可以在其中缩放和平移整个数据集.
以下是您所拥有的数据的示例,如加载到R,聚合等...
首先,将一些虚拟数据写入文件:
stime <- as.POSIXct("2011-01-01-00:00:00", format = "%Y-%d-%m-%H:%M:%S")
## dummy data
dat <- data.frame(Timestamp = seq(from = stime, by = 5, length = 2000000),
DD1 = sample(1:1000, replace = TRUE),
DD2 = sample(1:1000, replace = TRUE),
DD3 = sample(1:1000, replace = TRUE),
DD4 = sample(1:1000, replace = TRUE))
## write it out
write.csv(dat, file = "timestamp_data.txt", row.names = FALSE)
Run Code Online (Sandbox Code Playgroud)
然后我们可以在200万行中读取时间.为了加快速度,我们告诉R文件中列的类:"POSIXct"
是R中存储时间戳的一种方式.
## read it in:
system.time({
tsdat <- read.csv("timestamp_data.txt", header = TRUE,
colClasses = c("POSIXct",rep("integer", 4)))
})
Run Code Online (Sandbox Code Playgroud)
在我适度的笔记本电脑上,在内部unix时间内读取和格式化大约需要13秒.
user system elapsed
13.698 5.827 19.643
Run Code Online (Sandbox Code Playgroud)
聚合可以通过多种方式完成,一种是使用aggregate()
.假设聚合到小时平均值/平均值:
## Generate some indexes that we'll use the aggregate over
tsdat <- transform(tsdat,
hours = factor(strftime(tsdat$Timestamp, format = "%H")),
jday = factor(strftime(tsdat$Timestamp, format = "%j")))
## compute the mean of the 4 variables for each minute
out <- aggregate(cbind(Timestamp, DD1, DD2, DD3, DD4) ~ hours + jday,
data = tsdat, FUN = mean)
## convert average Timestamp to a POSIX time
out <- transform(out,
Timestamp = as.POSIXct(Timestamp,
origin = ISOdatetime(1970,1,1,0,0,0)))
Run Code Online (Sandbox Code Playgroud)
那个(创建线out
)在我的笔记本电脑上需要大约16秒,并提供以下输出:
> head(out)
hours jday Timestamp DD1 DD2 DD3 DD4
1 00 001 2010-12-31 23:29:57 500.2125 491.4333 510.7181 500.4833
2 01 001 2011-01-01 00:29:57 516.0472 506.1264 519.0931 494.2847
3 02 001 2011-01-01 01:29:57 507.5653 499.4972 498.9653 509.1389
4 03 001 2011-01-01 02:29:57 520.4111 500.8708 514.1514 491.0236
5 04 001 2011-01-01 03:29:57 498.3222 500.9139 513.3194 502.6514
6 05 001 2011-01-01 04:29:57 515.5792 497.1194 510.2431 496.8056
Run Code Online (Sandbox Code Playgroud)
使用以下plot()
功能可以实现简单的绘图:
plot(DD1 ~ Timestamp, data = out, type = "l")
Run Code Online (Sandbox Code Playgroud)
我们可以覆盖更多变量,例如:
ylim <- with(out, range(DD1, DD2))
plot(DD1 ~ Timestamp, data = out, type = "l", ylim = ylim)
lines(DD2 ~ Timestamp, data = out, type = "l", col = "red")
Run Code Online (Sandbox Code Playgroud)
或通过多个面板:
layout(1:2)
plot(DD1 ~ Timestamp, data = out, type = "l", col = "blue")
plot(DD2 ~ Timestamp, data = out, type = "l", col = "red")
layout(1)
Run Code Online (Sandbox Code Playgroud)
这一切都是基于R功能完成的.其他人已经展示了附加软件包如何使日期工作变得更容易.