我有一个JxK数据帧M,我想计算一下。
对于每一行j,使M[j,k]最小化的值k
对于每一列k,使M[j,k]最小化的值j
然后,让满足第一个的值是向量a_j,第二个是向量a_k。然后,我需要两个向量。设向量c为向量排序(c(a_j,a_k))。
长度等于a_j的向量,其中元素i是组合排序向量c中元素a_j[i]的索引。
长度等于A_k的向量,其中元素i是组合排序向量C中元素A_k[i]的索引。
对于上面提到的两个排序向量,所有的关系都应该给出该值出现在向量c中的第一个索引,也就是说,如果a_j[i]和a_j[i+1]相等,那么满足条件3的向量中的元素i和元素i+1应该都等于a_j[i]在排序向量c中的位置。
一如既往,这并不难做到低效。然而,在实际应用中,数据帧非常大,因此效率低下的解决方案失败了。
作为概念的证明,一种解决办法如下。

# Create the dataframe
set.seed(1)
df <- data.frame(matrix(rnorm(50, 8, 2), 10)) # A 10x5 matrix

# Calculate 1 and 2
A.j <- apply(df, 1, min)
A.k <- apply(df, 2, min)

# Calculate 3 and 4
C <- sort(unname(c(A.j, A.k)))

A.j.indices <- apply(df, 1, function(x) which(x == min(x)))
A.k.indices <- apply(df, 2, function(x) which(x == min(x)))

vec3out <- c()
vec4out <- c()

for(j in 1:nrow(df)){
   rank <- which(C == A.j[j])[1]
   vec3out <- c(vec3out, rank)
}

for(k in 1:ncol(df)){
   rank <- which(C == A.k[k])[1]
   vec4out <- c(vec4out, rank)
}

最佳答案

首先,你应该使用矩阵。Data.frames的效率较低(Should I use a data.frame or a matrix?)那么,我们应该使用apply函数。
设m为被强制为矩阵的data.frame。

M <- as.matrix(M)

minByRow <- apply(M, MARGIN=1, FUN=which.min)
minByCol <- apply(M, MARGIN=2, FUN=which.min)

combinedSorted <- sort(c(minByRow, minByCol))

byRowOutput <- match(minByRow, combinedSorted)
byColOutput <- match(minByCol, combinedSorted)

以下是100个变量的100万次观测结果:
M <- matrix(data=rnorm(100000000), nrow=1000000, ncol=100)


system.time({
  minByRow <- apply(M, MARGIN=1, FUN=which.min)
  minByCol <- apply(M, MARGIN=2, FUN=which.min)

  combinedSorted <- sort(c(minByRow, minByCol))

  byRowOutput <- match(minByRow, combinedSorted)
  byColOutput <- match(minByCol, combinedSorted)
})

   user  system elapsed
   7.37    0.46    7.93

07-24 09:51
查看更多