假设我有一个数据框,其中每列是一个方法,每一行都是这种方法的度量(越低越好)。
+----------+----------+
| 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 :(得分:2)
您实际上并不需要此矩阵中的许多数据点来保留所有相同的信息; Method 2
的{{1}}行(方法1节拍方法2次x次)将始终等于Method 1+
的{{1}}行(方法2输入方法1 x次数)。所以,我们可以像这样获得这些信息:
Method 1
这给了我们一个矩阵,其中每一行告诉我们行方法击败列方法的次数。例如,此处Method 2-
击败# 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
两次,而method2
击败method3
四次,method2
一次,等等。
我不知道这是不是#34;优雅&#34;您正在寻找的解决方案,但它应该比循环更快地工作,并为您提供具有所有相同信息的较小结果矩阵。