一个月前我曾问过类似的问题。请参阅 Count the occurrences of unequal numbers from a data frame
我使用outer
和Vectorize
函数解决了这个问题。我的解决方案如下:
dist_mat<- outer(1:nrow(df),1:nrow(df),
FUN = Vectorize( function(i,j) sum(df[i,]!=df[j,])))
这很完美,但现在我有一个超出我的内存大小的巨大矩阵。
在我得到dist_mat
后,对于每一行,我计算的列数小于或等于2,这是我现在无法做到的。所以,我想知道我是否可以在外部函数中组合计数操作以避免内存问题。我的结果只是一个向量。
提前谢谢!
答案 0 :(得分:1)
虽然这并没有严格回答您的问题,但您应该避免使用outer
并使用以下内容:
tot.rows <- nrow(df)
res <- numeric(tot.rows)
for(i in 1:tot.rows)
for(j in 1:tot.rows)
res[[i]] <- res[[i]] + (sum(df[i,] != df[j,]) <= 2)
outer
会从开始时预分配i * j
矩阵,因此您在使用外部时很难解决问题。如果您的结果实际上是与数据框长度相同的矢量,那么您不需要outer
在您的应用中生成尺寸为nrow(df) * nrow(df)
的矩阵。
上述算法将运行与outer
相同的计算次数,但每行重复使用相同的内存空间,因为您关心的是最终计数,因此它应该适合内存。 它也应该具有与外部相当的速度(这是我测试过的玩具示例)。矢量化操作很棒,只要你真的需要计算每个值,并且有内存来处理像outer
这样的完全扩展,但它们不一定是所有内容的答案。
正如其他人在上一个答案中指出的那样,你可以修改代码,这样你就不会计算对角线或矩阵的一个三角形,因为距离计算是对称的,这应该大致减半计算时间。
答案 1 :(得分:1)
如果您有矩阵DF,那么
apply(DF, 2, function(y) sum(colSums(DF==y) < 2))
可能有效吗? DF==y
将每列与apply
中的目标列进行比较,colSums
然后找出该列对中有多少行相等,然后将其与2(目标)进行比较作为DF == y的一部分,我总是把它作为自身的一部分进行比较,所以我考虑到了 - 你可能需要解决这个问题,这取决于你的'2'阈值是否包括自我比较)。最后sum
计算满足&lt; 2阈值的列数。
假设您不需要中间距离矩阵,它完全重新考虑了代码。