2016-02-01 122 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,]'? –