我的第一个问题是:如何应用一个有效的例程来迭代给定数据帧的两个向量(成对)的值?
更具体地说,请使用以下数据框考虑以下示例:
df0 <- data.frame(matrix(c(1,2,2,3,1,3,0.4,0.2,0.2,0.1,0.4,0.1),nrow=6,ncol=2))
colnames(df0) <- c("value","frequency")
第一列是实数值,第二列是频率(或权重)。注意:权重必须严格为正,它们可能会重复,它们不一定加起来(因为重复)。
我正在执行以下LOOP来计算我的函数P.这个P应该是0到1之间的数字。
# Define two parameters
K = 1/2
alpha = 0
# LOOP
mattemp <- matrix(,nrow=length(df0$value), ncol=length(df0$value))
for(i in 1:length(df0$value)) {
for(j in 1:length(df0$value)) {
mattemp[i,j] <- df0$frequency[i]^(1+alpha) * df0$frequency[j] * abs(df0$value[i]-df0$value[j])
P <- K * sum(mattemp)
}
}
基本上,我的函数P正在计算:
P = K * (0.4^alpha * 0.2 * |1-2| + 0.4^alpha * 0.1 * |1-3| + ...
只要矩阵很小,此代码就能很好地工作。
但是,我正在尝试为一个大矩阵(5400 x 5400)实现这个例程,而这个LOOP似乎没有找到结束。
我已经尝试使用foreach
命令(使用%dopar%
)循环它,但它也不起作用。
R可以处理一个聪明而简洁的例行程序吗?它不需要遵循上述结构,只要它是有效的。
非常感谢
答案 0 :(得分:3)
尝试:
df$nval <- (df0$value - mean(df0$value)) / sd(df0$value)
ij <- combn(nrow(df0), 2)
foo <- sum(df0$frequency[ij[1, ]] ^ (1 + alpha) * df0$frequency[ij[2, ]] * abs(df0$nval[ij[1, ]] - df0$nval[ij[2, ]]))
P <- K*2*sum(foo)
推理:基本上,您正在测试频率和标准化值之间的所有可能的排列。我们使用combn
创建其中的一半。然后,我们只是将整个事物矢量化。由于combn
仅提供唯一组合,因此我们需要乘以2. [请注意,我们不需要对角线上的值,因为abs(df0$value[i] - df0$value[i])
等于0
,并且我们只会遗漏i=j
和j=i
的情况,这就是我们乘以2的原因。]然后我们乘以K
得到P。
目前尚不清楚你想如何规范化,所以我只是减去均值并将其除以标准偏差。如果您有其他意思,您自己可以相应地改变它。
Edit1 :非常感谢@alexis_laz找到了一个错误并提出了几乎加倍速度的改进措施!
Edit2 :调整后的脚本以适应更改的要求。