在R中,我有两个矩阵,x和y,它们的列数相同,例如:
x <- matrix(runif(10*20),10,20)
y <- matrix(runif(50*20),50,20)
创建包含以下比较结果的矩阵的最有效方法是什么?将x中的每一行与y中的每一行(10x50行比较)进行比较,返回y行中的数字小于x行中的相应数字。将结果放在10x50结果矩阵中。
以下代码有效,但效率不高:
result <- matrix(NA,10,50)
for (i in 1:10) {
for (j in 1:50) {
result[i,j]<- sum(x[i,]>y[j,])
}
}
答案 0 :(得分:3)
确实你的代码没有运行,但我认为你的意思是y <- matrix(runif(50*20),50,20)
,对吗?
在这种情况下,您可以使用outer
功能:
outer(rowSums(x), rowSums(y), function(x, y) x > y)
修改
我明白你的意思,对不起,也可能因错误而得到了。我认为这将大大加快你的任务:
result2 <- rowSums(x[rep(1:nrow(x), nrow(y)), ] >
y[rep(1:nrow(y), each = nrow(x)), ]) %>%
matrix(nrow = nrow(x))
答案 1 :(得分:1)
我猜y <- matrix(runif(50))
你可以尝试使用单个循环来加速计算:
t(apply(y,1,function(u) rowSums(x<u)))
答案 2 :(得分:0)
这个答案基于@ ColonelBeauvel的回答。为了加快计算速度,您可以使用一个循环而不是两个循环并循环遍历较小的矩阵(在您的示例中为x
)。
t(apply(x, 1, function(u)colSums(u > t(y))))
另一个重要的注意事项是u < t(y)
。 R逐列比较矩阵,这就是为什么首先转置y
很重要的原因。
基准测试的完整示例:
set.seed(1)
x <- matrix(runif(10*20),10,20)
y <- matrix(runif(50*20),50,20)
f0 <- function(x, y) {
result <- matrix(NA,10,50)
for (i in 1:10) {
for (j in 1:50) {
result[i,j]<- sum(x[i,]>y[j,])
}
}
result
}
f1 <- function(x, y)t(apply(x,1,function(u)colSums(u>t(y))))
all.equal(f0(x, y), f1(x, y))
# [1] TRUE
benchmark(f0(x, y), f1(x, y), order="relative")
# test replications elapsed relative user.self sys.self user.child sys.child
# 2 f1(x, y) 100 0.035 1.000 0.032 0.004 0 0
# 1 f0(x, y) 100 0.253 7.229 0.252 0.000 0 0