2011-01-19 55 views
6

Tôi muốn sử dụng R để vẽ kết quả đánh giá hiệu suất của các hệ thống DB riêng biệt. Đối với mỗi hệ thống, tôi đã nạp cùng một dữ liệu và thực thi cùng một truy vấn trong một số lần lặp lại.tính trung bình trên nhiều khung dữ liệu

Các dữ liệu cho một hệ thống đơn trông như thế này:

"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 

Những gì tôi cần bây giờ (đối với âm mưu) là một khung ma trận hoặc dữ liệu có chứa tỷ lệ trung bình của các phép đo.

Hiện nay tôi đang làm điều này:

# 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 

tôi có thể đưa tất cả điều này vào một chức năng và tính toán ma trận trung bình trong một vòng lặp for, nhưng tôi có cảm giác mơ hồ rằng phải có một thanh lịch hơn dung dịch. Ý tưởng nào?

Tôi có thể làm gì cho các trường hợp khi tôi có kết quả không đầy đủ, ví dụ: khi một lần lặp có ít hàng hơn các hàng khác?

Cảm ơn!

Trả lời

3

Nếu tôi hiểu chính xác, trên hệ thống DB đã cho, trong mỗi "lần lặp" (1 ... N) bạn đang tải chuỗi DataSets (1,2,3) và chạy truy vấn trên chúng . Dường như cuối cùng bạn muốn tính thời gian trung bình trên tất cả các lần lặp lại, cho mỗi Số liệu. Nếu vậy, bạn thực sự cần phải có một cột bổ sung DataSet trong bảng all_results xác định Số liệu. Chúng ta có thể thêm cột này như sau:

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 

Bây giờ bạn có thể sử dụng chức năng ddply từ gói plyr để dễ dàng trích xuất giá trị trung bình cho tải và truy vấn lần cho mỗi DataSet.

> 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 

Ngẫu nhiên, tôi khuyên bạn nên bạn nhìn vào Hadley Wickham plyr package cho một tập hợp phong phú của dữ liệu thao tác chức năng

+0

thực sự thanh lịch hơn cho vòng lặp ... nhờ gợi ý. – behas

+0

nếu tôi muốn bao gồm cột "dòng" trong khung đầu ra của ddply? Tôi có thể làm điều đó bằng cách tính toán giá trị trung bình cũng trên các dòng; nhưng điều này bằng cách nào đó không có ý nghĩa vì các số dòng là giá trị tĩnh; – behas

+0

Tôi hiểu ý bạn là gì, nhưng tôi cho rằng không có hại gì khi lấy "trung bình" của một loạt các giá trị giống nhau! –

0

Hãy thử, ví dụ,

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

Bạn có có một cái gì đó như thế này trong tâm trí?

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

Hãy thử điều này:

> 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 

Một giải pháp aggregate mà cũng làm việc cho không cân bằng trường hợp sau. Giả sử rằng hàng thứ i của bất kỳ phép lặp nào là cho tập dữ liệu i và chúng ta chỉ đơn giản là trung bình trong các tập dữ liệu. Sử dụng aggregate là thẳng về phía trước. Phần khó khăn duy nhất là nhận được sự phân công của các hàng cho các tập dữ liệu chính xác để nó hoạt động trong trường hợp không cân bằng. Điều đó được thực hiện bởi biểu thức 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 
+0

Tôi đã nghĩ đến việc gợi ý điều tương tự, nhưng '+' không hoạt động nếu mọi 'data.frame' không cùng kích thước. –

+0

Các khung dữ liệu có cùng kích thước kể từ khi áp phích chỉ ra rằng mã mà anh ta đăng không hoạt động nhưng chỉ là anh ta muốn thứ gì đó "thanh lịch" hơn. –

+0

@Gabor Tôi đang đề cập đến câu cuối cùng trong câu hỏi của anh ấy. –

3

Tôi không hiểu tại sao bạn cần chia all_results theo iteration. Bạn chỉ có thể sử dụng aggregate trên all_results. Không cần tất cả các lần lặp lại có cùng số lượng quan sát.

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

Tôi nghĩ rằng OP cần trung bình bởi DataSet như tôi đã nói trong câu trả lời của tôi, không phải bởi "iteration" (nó không có ý nghĩa để lấy trung bình của một tập dữ liệu có 100000 dòng và một với 50000 dòng). Ít nhất đó là giải thích của tôi về những gì anh ta thực sự muốn làm. –

+0

... nhưng ý tưởng sử dụng 'tổng hợp' là tốt đẹp mặc dù (+1). Tôi chỉ cố gắng sử dụng nó như một bài tập để luyện tập sử dụng 'plyr'. –

Các vấn đề liên quan