R

时间:2016-02-01 19:59:31

标签: r

我的第一个问题是:如何应用一个有效的例程来迭代给定数据帧的两个向量(成对)的值?

更具体地说,请使用以下数据框考虑以下示例:

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可以处理一个聪明而简洁的例行程序吗?它不需要遵循上述结构,只要它是有效的。

非常感谢

1 个答案:

答案 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=jj=i的情况,这就是我们乘以2的原因。]然后我们乘以K得到P。

目前尚不清楚你想如何规范化,所以我只是减去均值并将其除以标准偏差。如果您有其他意思,您自己可以相应地改变它。

Edit1 :非常感谢@alexis_laz找到了一个错误并提出了几乎加倍速度的改进措施!

Edit2 :调整后的脚本以适应更改的要求。