2016-02-22 9 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