2015-12-31 81 views
0

相當一些谷歌的努力,我希望有人能幫助我解決這個問題,即顯得相當簡單,在我之後的所有可能組合的最好的一套,但也許是更復雜的比我想象:[R查找包括所有值

我有一個包含三列的data.frame。前兩個反映了五個變量(1-5)的所有可能組合,最後是組合的「強度」。我尋找五行,其中包括Var1和Var2的所有值(所以值爲1-5),並且在強度列中具有最高的總和。在下面的示例中,它是具有1000的強度的五行,因爲它們具有最高的總和,並且在前兩列中給出所有五個值(1-5)。

我該如何最好地解決這個問題?是否有一個包已經實現了這個任務?我現在發現了constrOptim()函數,我可以這樣做嗎?

代碼來創建一個實例數據框:

a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)), 
      strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54, 
         207, -32, 27, 128, 101, 19, -18, 32, 153, 14, 
         63, 136, 165, 73, 35)) 
a <- a[order(a$strength, decreasing=T),] 

開始數據集:

Var1 Var2 strength 
3 2  306 
3 1  230 
1 3  207 
2 2  169 
3 5  165 
5 1  156 
4 4  153 
2 5  136 
4 3  128 
4 1  118 
5 3  101 
1 2  98 
4 5  73 
1 5  63 
2 1  61 
5 5  35 
3 4  32 
3 3  27 
1 4  19 
5 4  14 
4 2  6 
1 1  -11 
2 4  -18 
2 3  -32 
5 2  -54 

不想要的結果:

Var1 Var2 strength 
3 2  306 
3 1  230 
1 3  207 
2 2  169 
3 5  165 

期望的結果:

Var1 Var2 strength 
3 2  306 
1 3  207 
5 1  156 
4 4  153 
2 5  136 
+6

你能顯示預期的輸出嗎? – akrun

+4

問題出在「所有變量用於第一列和第二列的地方......」。這是什麼意思? –

+0

最終解決方案應該有五行。前兩列(v1,v2)應該都具有從1到5的所有值。這是否清楚?我可以發佈一個例子,以後我會知道解決方案。這個例子是隨機的,因此我不知道解決方案。謝謝! –

回答

1

考慮一系列的aggregationmergesVar1Var2列之間:

# MERGE MAX AGGREGATES WHERE Var COL ARE EQUAL AND NOT EQUAL 
mergedf1 <- merge(aggregate(strength ~ Var1, data=a[a$Var1==a$Var2,], FUN=max), 
        a, by=c("Var1", "strength")) 
mergedf2 <- merge(aggregate(strength ~ Var1, data=a[a$Var1!=a$Var2,], FUN=max), 
        a, by=c("Var1", "strength")) 

# STACK RESULTS 
mergedf <- rbind(mergedf1, mergedf2) 

# FINAL MAX AGGREGATION AND MERGE 
final <- merge(aggregate(strength ~ Var2, data=mergedf, FUN=max), 
       mergedf, by=c("Var2", "strength")) 
final <- final[,c("Var1", "Var2", "strength")]     # SORT COLUMNS 
final <- final[with(final, order(-strength)),]     # SORT ROWS 

# REMOVE TEMP OBJECTS 
rm(mergedf1, mergedf2, mergedf) 
+0

謝謝,但我必須重新構思問題,以便反映我的問題。看到上面新的所需輸出。 –

+0

改變了什麼?我剛剛使用了你的數據框架示例並運行了上面的代碼。最終結果與您想要的結果相符。只要刪除'row.names()'行。 – Parfait

+0

嗨,對不起,我的例子不好。我做了一個新的。問題是每個值(1-5)都應該在Var1和Var2列中可用。如果我只是用力量來分類,這不一定是給出的。雖然在特定情況下可能。 –

1

我不知道所提出的解決方案是最有效的,但不知何故,我覺得我們必須在整個數據集查找唯一對(例如,將(Var1 = 2, Var2 = 5, strength = 136)的值更改爲(Var1 = 2, Var2 = 5, strength = 1)。爲了找到使用apply函數的唯一對。首先讓重新創建輸入:

a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)), 
      strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54, 
         207, -32, 27, 128, 101, 19, -18, 32, 153, 14, 
         63, 136, 165, 73, 35)) 
a <- a[order(a$strength, decreasing=T),] 

現在我準備一個空的矩陣,其中我將保持在第一列Var1Var2在第二和strength在第三列中。

V <- matrix(nrow = 5, ncol = 3) 

接下來,我寫一個函數,將有序數據集a得到一排,將檢查是否Var1Var2是獨一無二的,如果是這樣,將存儲實力。

mf <- function(x){ 
    if(!(x[1] %in% V[,1]) & !(x[2] %in% V[,2])) { 
     i <- x[1] 
     V[i,1] <<- x[1] 
     V[i,2] <<- x[2] 
     V[i,3] <<- x[3] 
    } 
} 

現在我申請的功能上的a每一行:

apply(a, 1, mf) 

所需的值存儲在矩陣V

V 
    [,1] [,2] [,3] 
[1,] 1 3 207 
[2,] 2 5 136 
[3,] 3 2 306 
[4,] 4 4 153 
[5,] 5 1 156 

但有時會在整個數據集是沒有必要的(就像給出的例子),那麼我們希望能夠在找到唯一對之後打破循環。爲此,我們可以使用for循環。這裏是代碼:

a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)), 
      strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54, 
         207, -32, 27, 128, 101, 19, -18, 32, 153, 14, 
         63, 136, 165, 73, 35)) 
a <- a[order(a$strength, decreasing=T),] 

V <- matrix(nrow=5,ncol=3) 
for (i in 1:nrow(a)) { 
    if(sum(is.na(V[,1])) == 0) 
     break 
    if(!(a[i,1] %in% V[,1]) & !(a[i,2] %in% V[,2])) { 
     j <- a[i,1] 
     V[j,1] <- a[i,1] 
     V[j,2] <- a[i,2] 
     V[j,3] <- a[i,3] 
    } 
} 

希望這有助於,或至少會導致改進。