Skip to content
This repository has been archived by the owner on Jan 21, 2021. It is now read-only.

Tips for the omnetpp r package

avarga edited this page Feb 28, 2012 · 7 revisions

Author: Tamas Borbely

How to transform the run attributes into 'wide' format?

The omnetpp dataset contains the run attributes in 'long' format:

> d$runattrs
                                          runid       attrname                            attrvalue
1 PureAlohaExperiment-0-20090220-15:51:12-31531     configname                  PureAlohaExperiment
2 PureAlohaExperiment-0-20090220-15:51:12-31531       datetime                    20090220-15:51:12
3 PureAlohaExperiment-0-20090220-15:51:12-31531     experiment                  PureAlohaExperiment
4 PureAlohaExperiment-0-20090220-15:51:12-31531        inifile                          omnetpp.ini
5 PureAlohaExperiment-0-20090220-15:51:12-31531  iterationvars                $numHosts=10, $mean=1
6 PureAlohaExperiment-0-20090220-15:51:12-31531 iterationvars2 $numHosts=10, $mean=1, $repetition=0
...

If you want to transform this into a 'wide' format (one column per attribute), you can use the cast function from the reshape package:

> cast(d$runattrs, runid~attrname, value='attrvalue')
                                           runid          configname          datetime          experiment     inifile         iterationvars                       iterationvars2 mean
1  PureAlohaExperiment-0-20090220-15:51:12-31531 PureAlohaExperiment 20090220-15:51:12 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=1 $numHosts=10, $mean=1, $repetition=0    1
2 PureAlohaExperiment-10-20090220-15:51:14-31542 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=7 $numHosts=10, $mean=7, $repetition=0    7
3 PureAlohaExperiment-11-20090220-15:51:14-31543 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=7 $numHosts=10, $mean=7, $repetition=1    7
4  PureAlohaExperiment-1-20090220-15:51:12-31532 PureAlohaExperiment 20090220-15:51:12 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=1 $numHosts=10, $mean=1, $repetition=1    1
5 PureAlohaExperiment-12-20090220-15:51:14-31544 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=9 $numHosts=10, $mean=9, $repetition=0    9
6 PureAlohaExperiment-13-20090220-15:51:14-31545 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=9 $numHosts=10, $mean=9, $repetition=1    9
            measurement network numHosts processid repetition replication resultdir runnumber seedset
1 $numHosts=10, $mean=1   Aloha       10     31531          0          #0   results         0       0
2 $numHosts=10, $mean=7   Aloha       10     31542          0          #0   results        10      10
3 $numHosts=10, $mean=7   Aloha       10     31543          1          #1   results        11      11
4 $numHosts=10, $mean=1   Aloha       10     31532          1          #1   results         1       1
5 $numHosts=10, $mean=9   Aloha       10     31544          0          #0   results        12      12
6 $numHosts=10, $mean=9   Aloha       10     31545          1          #1   results        13      13
...

If you want to restrict the attribute columns:

> cast(d$runattrs, runid~attrname, value='attrvalue', subset=attrname %in% c('experiment','measurement','replication'))
                                           runid          experiment           measurement replication
1  PureAlohaExperiment-0-20090220-15:51:12-31531 PureAlohaExperiment $numHosts=10, $mean=1          #0
2 PureAlohaExperiment-10-20090220-15:51:14-31542 PureAlohaExperiment $numHosts=10, $mean=7          #0
3 PureAlohaExperiment-11-20090220-15:51:14-31543 PureAlohaExperiment $numHosts=10, $mean=7          #1
4  PureAlohaExperiment-1-20090220-15:51:12-31532 PureAlohaExperiment $numHosts=10, $mean=1          #1
5 PureAlohaExperiment-12-20090220-15:51:14-31544 PureAlohaExperiment $numHosts=10, $mean=9          #0
6 PureAlohaExperiment-13-20090220-15:51:14-31545 PureAlohaExperiment $numHosts=10, $mean=9          #1
...

How to transform a dataset into another dataset where all scalars are averaged across replications?

First add the 'experiment' and 'measurement' columns to the scalars:

> scalars <- merge(d$scalars,
                   cast(d$runattrs, runid~attrname, value='attrvalue', subset=attrname %in% c('experiment','measurement')),
                   by='runid',
                   all.x=TRUE)

Now you can compute the averages by calling cast() again:

> cast(scalars, experiment+measurement+module+name ~ ., mean)

To compute confidence intervals as well:

> ci95 <- conf.int(0.95)
> cast(scalars, experiment+measurement+module+name ~ ., c(mean,ci95))

How to average some scalars across modules?

For example, if you want the average of 'avgQueueLength' across all queue modules per run:

> cast(d$scalars, runid~name, mean, subset=grepl('.*\\.queue', module) & name=='avgQueueLength')

If you want to average for the runs too:

> cast(d$scalars, .~name, mean, subset=grepl('.*\\.queue', module) & name=='avgQueueLength')

How to sum scalars grouped by modules?

Assume you want to compute the sum of drop counts for each node in the 'omnetpp/samples/routing/Net60' network.

First load the scalars generated by the simulation:

> d <- loadDataset('/home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca')

Each node may have several input gates and a message queue for each input port. You can select the drop counts of the queues by:

> dc <- subset(d$scalars, name=='drop:count' & grepl('.*queue.*',module))
> dc

     resultkey                          runid                                                        file                 module       name value
10           9 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[0].queue[0] drop:count     0
21          20 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[1].queue[0] drop:count     0
30          29 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[1].queue[1] drop:count     0
39          38 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[1].queue[2] drop:count     0
50          49 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[2].queue[0] drop:count     0
61          60 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[3].queue[0] drop:count     0
72          71 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[4].queue[0] drop:count    12
81          80 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[4].queue[1] drop:count     0
90          89 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[4].queue[2] drop:count     0
99          98 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[4].queue[3] drop:count     0
...

To sum the drop counts for each node:

> r <- aggregate(list(value=dc$value),
                 list(runid=dc$runid,file=dc$file,module=sub('\\.queue\\[[0-9]+\\]', '', dc$module),name=dc$name),
                 sum)
> head(r)
                           runid                                                        file        module       name value
1 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[0] drop:count     0
2 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca  Net60.rte[1] drop:count     0
3 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[10] drop:count     6
4 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[11] drop:count     0
5 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[12] drop:count     0
6 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[13] drop:count     0

If you want to add these scalars to the original dataset, first generate resultkey for the new scalars, and use rbind:

> r <- cbind(list(resultkey=seq(from=nextResultKey(d), length.out=nrow(r))), r)
> d$scalars <- rbind(d$scalars, r)

How to compute the mean, stddev, min, max etc of vectors?

The current version of the omnetpp package does not support computing the summary statistics without loading the vectors, but it is planned in a future version to do so.

So first load the vectors into the memory:

> d <- loadDataset('Aloha.vec', add('vector'))
> d <- loadVectors(d, NULL)

Using the base package

If the vector is loaded into a dataset, then the mean, sd, min, max functions can be used:

> vs <- split(d$vectordata$y, d$vectordata$resultkey)
> lapply(vs, mean)
> lapply(vs, sd)
> lapply(vs, min)
> lapply(vs, max)
> lapply(vs, summary)

Using the reshape package

Its much simpler:

> cast(d$vectordata, resultkey~., c(mean,sd,min,max), value='y')

Using the doBy package

If you have the doBy package installed:

> require(doBy)
> summaryBy(y ~ resultkey, d$vectordata, FUN = list(mean, sd, min, max))

How to plot vectors?

Using the lattice package

Altough the plot() function in the graphics package can create line plots, it is not good for drawing several lines on the same plot. We suggest to use the lattice package instead.

The 'xyplot()' function accepts a formula identifying the 'x' and 'y' data, and a data frame containing the data. You can also filter the rows of the dataset by specifying the 'subset' argument. Therefore if d is an omnetpp dataset containing the vectors data, you can plot a specific vector by:

> require(lattice)
> xyplot(y~x, d$vectordata, subset=resultkey==2, type='l')

If you want to plot all vectors contained by the dataset:

> require(lattice)
> xyplot(y~x, d$vectordata, groups=resultkey, auto.key=TRUE)

Using the omnetpp package

The omnetpp package contains a plotLineChart() function. This function is intended to produce the same line charts as the OMNeT++ IDE.

This functions accept a list of lines as first argument, where each line is a data frame or matrix with 'x' and 'y' numeric columns sorted by 'x'.

> x <- seq(0,10,0.1)
> plotLineChart(list(a=data.frame(x=x, y=sin(x)),
                     b=data.frame(x=x, y=cos(x))))

In this example the lines are named 'a' and 'b'.

The plotLineChart() function supports the graphical properties that can be set in the IDE.

> plotLineChart(list(a=data.frame(x=x, y=sin(x)),
                     b=data.frame(x=x, y=cos(x)),
                     c=data.frame(x=x, y=runif(length(x)))),
                Legend.Display = 'true',
                'Line.Color/a'='red', 'Symbols.Type/b'='Square', 'Line.Type/c'='SampleHold')

If you want to generate a plot from vectors in a dataset, use the makeLineChartDataset() function. The function builds the structure for plotLineChart from all vectors in the dataset and names the lines according to the specified format string.

> vs <- makeLineChartDataset(dataset, '${configname}/${runnumber} - ${module} ${name}')
> plotLineChart(vs, Legend.Display='true')

How to compute and plot a histogram of a vector?

Using the graphics package

If v is a numeric vector, then the hist() function from the graphics package can be used to generate a histogram object and draw a histograme plot.

> h <- hist(v)

If you want to put several histogram on a single plot:

> h1 <- hist(v1, plot=FALSE)
> h2 <- hist(v2, plot=FALSE)
> plot(h1)
> plot(h2, add=TRUE)

Using the lattice package

> histogram(~y, d$vectordata, groups=resultkey)

Using the ggplot2 package

> qplot(y, data=d$vectordata, group=resultkey, geom='histogram', binwidth=1)

or

> ggplot(d$vectordata, aes(x=y, group=resultkey)) + geom_histogram(binwidth=1)

How to plot the histograms loaded from scalar files?

If d is a loaded dataset containing histogram data, then makeHistograms() can generate histogram objects:

> hs <- makeHistograms(d, '{module} {name}') 

The result is a list of histgram objects, the elements are identified by module and statistic name. This list can be plotted by the plotHistogramChart function.

> plotHistograms(hs)

How to plot a histogram together with its cumulative distribution function?

Using the lattice package

> histogram( ~ y, data = d$vectordata, subset=resultkey==2,
            type = "density",
            panel = function(x, ...) {
                panel.histogram(x, ...)
                panel.densityplot(x, ...)
            } )

Using the ggplot package

> ggplot(d$vectordata, aes(x=y, group=resultkey)) + geom_histogram(binwidth=1) + geom_density()

How to create a bar chart of some scalars where error bars indicate confidence interval?

Using the lattice package

Based on http://stackoverflow.com/questions/2381618

> prepanel.ci <- function(x, y, ly, uy, subscripts, ...) {
      y <- as.numeric(y)
      ly <- as.numeric(ly[subscripts])
      uy <- as.numeric(uy[subscripts])
      list(ylim = range(0, y, uy, ly, finite = TRUE))
  }


> panel.ci <- function(x, y, ly, uy, subscripts, box.ratio=1, box.width=box.ratio/(1+box.ratio), groups, ...) {
      panel.barchart(x, y, subscripts=subscripts, groups=groups, box.ratio=box.ratio, box.width=box.width, ...)
      groups <- as.factor(groups)
      nvals <- nlevels(groups)
      width <- box.width / nvals
      x <- as.numeric(x)
      y <- as.numeric(y)
      ly <- as.numeric(ly[subscripts])
      uy <- as.numeric(uy[subscripts])
      groups <- as.numeric(groups)
      x0 <- x + width * (groups - (nvals + 1) / 2)
      panel.arrows(x0, ly, x0, uy, length=0.25*width, unit='npc',
      angle=90, code=3, col='black')
  }

> barchart(mean ~ name, data=scalars, groups=measurement,
           horizontal=FALSE, ly=scalars$mean-scalars$ci95, uy=scalars$mean+scalars$ci95,
           panel=panel.ci, prepanel=prepanel.ci)

Using the ggplot2 package

> require(ggplot2)
> ggplot(scalars, aes(x=name, y=mean, fill=measurement)) +
    geom_bar(position='dodge') +
    geom_errorbar(aes(ymin=mean-ci95, ymax=mean+ci95), position='dodge')

Using the omnetpp package

> means <- makeBarChartDataset(dataset, rows='name', columns='measurement')
> ci95 <- makeBarChartDataset(dataset, rows='name', columns='measurement', conf.int(0.95) )
> plotBarChart(means, conf.int=ci95, Legend.Display='true', Legend.Anchoring='NorthWest')

How to plot a scatter chart where the X axis is some run iteration variable (i.e. $numHosts)?

Iteration variables are saved as scalars as well, so you can write:

> d <- makeScatterChartDataset(dataset, xModule='.', xName='numHosts')
> plotLineChart(d)

How to plot a 3D chart where the X,Y axes are run iteration variables?

In this example we create a 3D plot of the total receive time as a function of the mean iaTime and numOfHosts from the Aloha simulation.

First create a data frame containing the values of the scalars for each run:

> d <- loadDataset('/home/tomi/work/omnetpp-resultfiles/R-package/inst/extdata/PureAlohaExperiment-*.sca')
> data3d <- cast(d$scalars, runid ~ name, subset=name%in%c('mean','numHosts','total receive time'))

Now you can use the lattice package to draw a 3D scatter plot (cloud()) or a 3D surface plot (wireframe()):

> require(lattice)
> cloud(`total receive time` ~ numHosts * mean, data=data3d)