2017-10-19 152 views
0

假设我有一个数据框,其中每列是一个方法,每一行是这种方法的度量(越低越好)。矩阵R与方法之间的胜负计数

+----------+----------+ 
| Method 1 | Method 2 | 
+----------+----------+ 
|  1 |  2 | 
|  2 |  3 | 
+----------+----------+ 

我想获得与输赢的所有方法(可能不仅仅是两个)之间的计数的数据帧,一种方法获得,如果它有一个比另一个更小的度量。像这样:

+----------+-----------+-----------+-----------+-----------+ 
|   | Method 1+ | Method 1- | Method 2+ | Method 2- | 
+----------+-----------+-----------+-----------+-----------+ 
| Method 1 |   - |   - |   0 |   2 | 
| Method 2 |   2 |   0 |   - |   - | 
+----------+-----------+-----------+-----------+-----------+ 

其中方法名称中的“+”表示方法获胜或丢失时“ - ”。

微不足道的方法是迭代数据帧的每一行,并在所有列对之间进行比较,但效率很低。

R有没有更优雅的解决方案?

+0

在你的问题中包括一个[最小可重现的例子](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)将增加你获得答案的机会。 – jsb

+0

你也许想要概述你的赢/输逻辑是如何工作的,或者你如何从你的输入中得到你想要的结果。 –

回答

2

实际上,您并不需要这个矩阵中的许多数据点来保存所有相同的信息; (方法1击败方法2×次数)将总是等于行的Method 2-(方法2丢失到方法1×次数)。因此,我们可以得到如下信息:

# First we make a function to count the wins in two columns 
# (this will be useful later to feed to apply) 
count_wins <- function(columns, data) { 
    return(sum(data[ , columns[1]] < data[ , columns[2]])) 
} 
# Then we set the seed for some reproducible data 
set.seed(123) 
# Create some random example data 
df <- data.frame(method1=sample(1:10, 5, replace=TRUE), 
         method2=sample(1:10, 5, replace=TRUE), 
         method3=sample(1:10, 5, replace=TRUE)) 
# method1 method2 method3 
# 1  3  1  10 
# 2  8  6  5 
# 3  5  9  7 
# 4  9  6  6 
# 5  10  5  2 
# We make an empty matrix to store results 
result <- matrix(NA, nrow=ncol(df), ncol=ncol(df)) 
# Create a matrix of all column pairings 
combos <- combn(x=ncol(df), m=2) 
# And use apply, upper/lower.tri, and count_wins to fill the matrix 
result[upper.tri(result)] <- apply(combos, 2, count_wins, df) 
result[lower.tri(result)] <- apply(combos[2:1,], 2, count_wins, df) 
# Then we just name the rows and columns 
rownames(result) <- colnames(result) <- paste0('method', 1:3) 
#   method1 method2 method3 
# method1  NA  1  2 
# method2  4  NA  1 
# method3  3  3  NA 

这给了我们一个矩阵,其中每行告诉我们行方法击败列方法的次数。例如,这里跳动method1一次method2method3两次,而method2method1四次method3一次,等

我不知道这是不是你要找的“优雅”的解决方案,但它应该工作比循环更快,并为您提供所有相同信息的较小结果矩阵。

+0

这是有效的!谢谢@duckmayr(不知道'combn'方法,它真的很棒!) –