我正在尝试编写一个 for 循环来比较两个人之间的值,但不是同一个人。以下数据框包含五个主题的值:
Value1
Subject1 0
Subject2 1
Subject3 5
Subject4 6
Subject5 8
我编写了一个双循环,它根据以下标准创建一个“Value2”变量:
例如,科目 1 的值 1 小于其他四个科目;这应该导致-4。到目前为止,我编写的循环适用于第一个主题,但无法迭代到第二个主题。
Value2<-0
i = 0
w = 0
for(i in 1:length(Value1)){
for(j in 1:length(Value1)){
if(i != j){
Value1[i] = w
if(w > Value1[j]){
Value2[i] = Value2[i] + 1
}
if(w < Value1[j]){
Value2[i] = Value2[i] - 1
}
if(w == Value1[j]){
Value2[i] = Value2[i] + 0
}
}
}
}
最佳答案
如果我正确理解问题,这应该给你你想要的
x <- c(0, 1, 5, 6, 8)
colSums(outer(x, x, '<')) - colSums(outer(x, x, '>'))
# [1] -4 -2 0 2 4
或者
-colSums(sign(outer(x, x, '-')))
# [1] -4 -2 0 2 4
编辑:如果你的向量很大(或者即使不是,真的)使用 d.b. 的
rank
方法代替 . outer
函数将创建一个 NxN 矩阵,其中 N 是 x
的长度.例如,当 x
是 sample(1e5)
outer
将尝试创建一个大于 30Gb 的矩阵!这意味着 2019 年大多数人的笔记本电脑甚至没有足够的内存来使用这种方法来处理大型向量。与此相同 x
,方法使用rank
由 d.b. 提供几乎立即返回结果。大小为 1000 的向量的基准
x <- sample(1000)
microbenchmark(
outer_diff = colSums(-sign(outer(x, x, '-'))),
outer_gtlt = colSums(outer(x, x, '<')) - colSums(outer(x, x, '>')),
rank = {r <- rank(x); 2*(r - mean(r))}
)
# Unit: microseconds
# expr min lq mean median uq max neval cld
# outer_diff 15930.26 16872.4175 20946.2980 18030.776 25346.677 38668.324 100 b
# outer_gtlt 14168.21 15120.4165 28970.7731 16698.264 23857.651 352390.298 100 b
# rank 111.18 141.5385 170.8885 177.026 188.513 282.257 100 a
关于arrays - R中的元素比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57171218/