2016-02-01 124 views
1

我的第一个问题是:如何应用一个有效的例程来迭代给定数据帧的两个向量的值(成对)?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") 

的第一列是一个真正的值,第二列是一个频率(或权重)。注意:重量必须是严格正面的,它们可能会重复,它们不一定加起来(因为重复)。

我执行以下循环来计算我的函数P.这P被认为是一个数

# 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) 
    } 
} 

基本上0和1之间

,我的函数P被计算:

P = K * (0.4^alpha * 0.2 * |1-2| + 0.4^alpha * 0.1 * |1-3| + ... 

只要矩阵很小,此代码就可以很好地工作。

但是,我正在尝试为大矩阵(5400 x 5400)实现此例程,并且此LOOP似乎没有找到结尾。

我已经尝试使用foreach命令(使用%dopar%)来循环它,但它不起作用。

R是否有一个聪明而简洁的例程?只要效率高,它不需要遵循上述结构。

非常感谢您

回答

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.

目前还不清楚你想如何归一化,所以我只是将平均值减去,并用标准偏差除。如果你的意思是别的,你自己可以相应地改变它。

编辑1:非常感谢@alexis_laz发现一个错误,并建议将速度提高一倍!

编辑2:调整的脚本以适应更改的要求。

+1

这看起来不错。 – RHertel

+0

你确定这里有这个步骤:'vald < - abs(val [,1] - val [,2])'?你得到P = 0.02,我得到P = 0.18。 –

+1

或许,你可以避免在索引('combn(nrow(df0),2)')上调用'combn'两次,然后索引“value”和“frequency”。另外,'[,1]'和'[,2]'应该分别是'[1,]'和'[2,]'? –