2016-02-22 11 views
0

我正在嘗試構建一個決策表。例如,在時間3時,我必須在時間t = 1和時間t = 2時採取以前的結果,以便在時間3做出我的決定。決策表將會非常大,所以我正在考慮一種有效的方法來做它通過構建一個函數。例如在時間3:以動態方式擴展條件

rm(list=ls()) # clear memory 
names <- c("a","b","c","d","e","f","g","h","i","j","k50","l50","m50","n50","o50") 

proba <- c(1,1,1,1,1,1,1,1,1,1,0.5,0.5,0.5,0.5,0.5) 
need <- 4 
re <- 0.5 
w <- 1000000000 

    # t1 
    t1 <- as.integer(names %in% (sample(names,need,prob=proba,replace=F))) 

    # t2 
    t2 <- rep(t1) 

    # t3 
    proba3 <- ifelse(t2==1,proba*re,proba) 
    t3 <- as.integer(names %in% (sample(names,need,prob=proba3,replace=F))) 

現在表將是大直到與proba7 T = 7這需要條件從t = 1到t = 6。在t = 7之後,爲了做出決定,總是需要6個以前的結果加上隨機部分的概率。換句話說,ifelse必須是動態的,以便以後可以調用它。我一直在嘗試像

probF <- function(a){ 
    test <- ifelse(paste0("t",a,sep="")==1,proba*re,proba) 
    return(test) 
} 

test <- probF(2) 

但有一個錯誤,因爲我只有一個值,而不是一個向量。我知道這看起來複雜

對於由一個人所要求的條件(我知道這是不太好寫的):

proba7 <- ifelse(t2==1 & t3==1 & t4==0 & t5==0 & t6==0,proba, 
       ifelse(t2==1 & t3==0 & t4==0 & t5==1 & t6==1,proba*re, 
         ifelse(t2==1 & t3==0 & t4==0 & t5==0 & t6==1, w, 
           ifelse(t2==0 & t3==1 & t4==1 & t5==0 & t6==0,proba, 
             ifelse(t2==0 & t3==1 & t4==1 & t5==1 & t6==0,0, 
              ifelse(t2==0 & t3==0 & t4==1 & t5==1 & t6==1,0, 
                ifelse(t2==0 & t3==0 & t4==1 & t5==1 &t6==0,0, 
                  ifelse(t2==0 & t3==0 & t4==0 & t5==1 & t6==1, proba*re, 
                    ifelse(t2==0 & t3==0 & t4==0 & t5==0 & t6==1,w,proba))))))))) 

t7 <- as.integer(names %in% (sample(names,need,prob=proba7,replace=F))) 
+3

聽起來很糟糕的方法來解決這個問題,因此這個問題似乎是[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。你想做什麼 ? – Tensibai

+0

我正在做一個決策表。然而,時間t的決定取決於給定加上隨機效應的t-6到t-1的先前決定。但你是對的我的問題不是很清楚我要更新它 – richpiana

+0

@Tensibai我編輯了我的所有問題,以便更清楚,這有幫助嗎? – richpiana

回答

1

如果你需要一些不同的方法,你會獲得相當很多速度。

首先,將每一步作爲單獨的t1,proba1等存儲是一個非常糟糕的主意。如果您需要保留所有信息,預定義矩陣或正確大小的列表並將所有內容存儲在那裏。這樣你就可以使用簡單的索引,而不必求助於易於使用錯誤的get()。如果你發現自己打字get(),幾乎總是停下來重新考慮你的解決方案。

其次,你可以使用一個簡單的原則來選擇t檢驗的指標:

seq(max(0, i-7), i-1) 

將允許您使用循環索引i,如果它們存在參考以前的6個位置。

第三,根據您的需要,您也可以重新制定您的決定。如果將每個t存儲在矩陣中,則可以簡單地使用colSums()並檢查該值是否大於0.根據該索引,可以更新概率,使得前面的6中的1行半數的概率。然後

在功能包裝的一切看起來像:

myfun <- function(names, proba, need, re, 
        w=100){ 

    # For convenience, so I don't have to type this twice 
    resample <- function(p){ 
    as.integer(
     names %in% sample(names,need,prob=p, replace = FALSE) 
    ) 
    } 
    # get the number of needed columns 
    nnames <- length(names) 

    # create two matrices to store all the t-steps and the probabilities used 
    theT <- matrix(nrow = w, ncol = nnames) 
    theproba <- matrix(nrow = w, ncol = nnames) 

    # Create a first step, using the original probabilities 
    theT[1,] <- resample(proba) 
    theproba[1,] <- proba 

    # loop over the other simulations, each time checking the condition 
    # recalculating the probability and storing the result in the next 
    # row of the matrices 

    for(i in 2:w){ 

    # the id vector to select the (maximal) 6 previous rows. If 
    # i-6 is smaller than 1 (i.e. there are no 6 steps yet), the 
    # max(1, i-6) guarantees that you start minimal at 1. 
    tid <- seq(max(1, i-6), i-1) 

    # Create the probability vector from the original one 
    p <- proba 
    # look for which columns in the 6 previous steps contain a 1 
    pid <- colSums(theT[tid,,drop = FALSE]) > 0 
    # update the probability vector 
    p[pid] <- p[pid]*0.5 

    # store the next step and the used probabilities in the matrices 
    theT[i,] <- resample(p) 
    theproba[i,] <- p 

    } 

    # Return both matrices in a single list for convenience 
    return(list(decisions = theT, 
       proba = theproba) 
) 
} 

可以用來爲:

myres <- myfun(names, proba, need, re, w) 
head(myres$decisions) 
head(myres$proba) 

這將返回一個矩陣,其中每一行是決定一個T-點表。

+0

@ Joris Meys哇,這真是太好了,我會小心翼翼地理解它,但請給我一些時間,因爲我是一個R用戶。我非常感謝你的幫助 – richpiana

+0

@branchwarren我可能誤會了你的病情。我已經更新了我的回答,因此它現在會檢查在前面的6個步驟中選擇了哪個名稱。如果您需要更多解釋,請拍攝。 –

+0

@ Joris Meys:我把上面的條件(在這個問題中,如果有幫助的話) – richpiana