我正在尝试编写一个for循环,该循环将比较两个人之间的值,而不是同一个人。以下数据框包含五个主题的值:
Value1
Subject1 0
Subject2 1
Subject3 5
Subject4 6
Subject5 8
Run Code Online (Sandbox Code Playgroud)
我编写了一个双循环,该循环根据以下条件创建“ Value2”变量:
例如,主题1的Value1小于其他四个主题;这应该导致-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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我正确地理解了问题,这应该给您您想要的
x <- c(0, 1, 5, 6, 8)
colSums(outer(x, x, '<')) - colSums(outer(x, x, '>'))
# [1] -4 -2 0 2 4
Run Code Online (Sandbox Code Playgroud)
要么
-colSums(sign(outer(x, x, '-')))
# [1] -4 -2 0 2 4
Run Code Online (Sandbox Code Playgroud)
编辑:如果向量很大(或者实际上不是很大),请改用db的rank方法。该outer函数将创建一个NxN矩阵,其中N是的长度x。例如,当x是sample(1e5) outer将尝试创建一个矩阵> 30GB的大小!这意味着2019年大多数人的笔记本电脑甚至没有足够的内存来使用这种方法处理大型矢量。与此相同x,rankdb提供的using方法几乎立即返回了结果。
大小为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
Run Code Online (Sandbox Code Playgroud)
x = c(0, 1, 5, 6, 8)
r = rank(x)
ans = 2 * (r - mean(r))
ans
#[1] -4 -2 0 2 4
Run Code Online (Sandbox Code Playgroud)