计算多个数据帧的平均值

时间:2011-01-19 16:19:11

标签: r

我想用R来绘制不同数据库系统的性能评估结果。对于每个系统,我加载了相同的数据,并在几次迭代中执行相同的查询。

单个系统的数据如下所示:

"iteration", "lines", "loadTime", "query1", "query2", "query3"
1, 100000, 120.4, 0.5, 6.4, 1.2
1, 100000, 110.1, 0.1, 5.2, 2.1
1, 50000, 130.3, 0.2, 4.3, 2.2

2, 100000, 120.4, 0.1, 2.4, 1.2
2, 100000, 300.2, 0.2, 4.5, 1.4
2, 50000, 235.3, 0.4, 4.2, 0.5

3, 100000, 233.5, 0.7, 8.3, 6.7
3, 100000, 300.1, 0.9, 0.5, 4.4
3, 50000, 100.2, 0.4, 9.2, 1.2

我现在需要(用于绘图)是包含这些测量的平均值的矩阵或数据帧。

目前我正在这样做:

# read the file
all_results <- read.csv(file="file.csv", head=TRUE, sep=",")

# split the results by iteration
results <- split(all_results, all_results$iteration)

# convert each result into a data frane
r1 = as.data.frame(results[1])
r2 = as.data.frame(results[2])
r3 = as.data.frame(results[3])

# calculate the average
(r1 + r2 +r3) / 3

我可以把所有这些都放到一个函数中并计算for循环中的平均矩阵,但我有一种模糊的感觉,那就是必须有一个更优雅的解决方案。有什么想法吗?

如果我的结果不完整,例如,当一次迭代的行数少于其他行时,我该怎么办?

谢谢!

5 个答案:

答案 0 :(得分:3)

如果我理解正确,在给定的数据库系统上,在每个“迭代”(1 ... N)中,您正在加载一系列DataSet(1,2,3)并对它们运行查询。最后,您似乎想要计算所有迭代的平均时间,为每个DataSet 。如果是这样,您实际上需要在DataSet表中添加一个标识DataSet的列all_results。我们可以按如下方式添加此列:

all_results <- cbind( data.frame( DataSet = rep(1:3,3) ), all_results )
> all_results
  DataSet iteration  lines loadTime query1 query2 query3
1       1         1 100000    120.4    0.5    6.4    1.2
2       2         1 100000    110.1    0.1    5.2    2.1
3       3         1  50000    130.3    0.2    4.3    2.2
4       1         2 100000    120.4    0.1    2.4    1.2
5       2         2 100000    300.2    0.2    4.5    1.4
6       3         2  50000    235.3    0.4    4.2    0.5
7       1         3 100000    233.5    0.7    8.3    6.7
8       2         3 100000    300.1    0.9    0.5    4.4
9       3         3  50000    100.2    0.4    9.2    1.2

现在,您可以使用ddply包中的plyr函数轻松提取每个数据集的加载和查询时间的平均值。

> ddply(all_results, .(DataSet), colwise(mean, .(loadTime, query1, query2)))
  DataSet loadTime    query1 query2
1       1 158.1000 0.4333333    5.7
2       2 236.8000 0.4000000    3.4
3       3 155.2667 0.3333333    5.9

顺便提一下,我强烈建议您查看Hadley Wickham的plyr package以获取丰富的数据操作功能

答案 1 :(得分:3)

我不明白为什么你需要将all_results分割为iteration。您可以在aggregate上使用all_results。所有迭代都不需要具有相同数量的观察值。

Lines <- "iteration, lines, loadTime, query1, query2, query3
1, 100000, 120.4, 0.5, 6.4, 1.2
1, 100000, 110.1, 0.1, 5.2, 2.1
1, 50000, 130.3, 0.2, 4.3, 2.2
2, 100000, 120.4, 0.1, 2.4, 1.2
2, 100000, 300.2, 0.2, 4.5, 1.4
2, 50000, 235.3, 0.4, 4.2, 0.5
3, 100000, 233.5, 0.7, 8.3, 6.7
3, 100000, 300.1, 0.9, 0.5, 4.4
3, 50000, 100.2, 0.4, 9.2, 1.2"

all_results <- read.csv(textConnection(Lines))

aggregate(all_results[,-1], by=all_results[,"iteration",drop=FALSE], mean)

答案 2 :(得分:1)

你有没有这样的想法?

do.call("rbind", lapply(results, mean))

答案 3 :(得分:1)

试试这个:

> Reduce("+", results) / length(results)
  DataSet iteration lines loadTime    query1 query2   query3
1       1         2 1e+05 158.1000 0.4333333    5.7 3.033333
2       2         2 1e+05 236.8000 0.4000000    3.4 2.633333
3       3         2 5e+04 155.2667 0.3333333    5.9 1.300000

一个aggregate解决方案也适用于不平衡的情况。假设任何迭代的第i行用于数据集i,并且我们只是在数据集中进行平均。使用aggregate是直截了当的。唯一棘手的部分是将行分配给数据集是正确的,这样它也可以在不平衡的情况下工作。这是由list(data.set = ...)表达式完成的。

> it <- all_results$iteration
> aggregate(all_results, list(data.set = seq_along(it) - match(it, it) + 1), mean)
  data.set iteration lines loadTime    query1 query2   query3
1        1         2 1e+05 158.1000 0.4333333    5.7 3.033333
2        2         2 1e+05 236.8000 0.4000000    3.4 2.633333
3        3         2 5e+04 155.2667 0.3333333    5.9 1.300000

答案 4 :(得分:0)

尝试,例如,

with(all_results, tapply(lines, iteration, mean))