关于R中while循环的问题

时间:2010-12-28 15:40:34

标签: r

进一步更新

没有输入,因为程序会创建数据。

以下代码适用于前两位患者,但我想把它放在一个循环中;最终将有200名患者。抱歉长度。

    s <- 42 #SHOULD BE 42
    p <- 30 #SHOULD BE 400
    p1 <- 8 #Should be 8
    m <- 2 #shou;ld be higher
    w <- 2
    #CAPITAL LETTERS are counting versions of the lowercase
    numses <- 12
    mult <- 1
    maxses <- round(mult*numses,0)
    drop = .3; titrate = .2;  complete = .3; noise = .5; other = .1
    dropskip = .3; titrateskip = .2; completeskip = .3; noiseskip = .5; otherskip = .1;
    dropnew = .3; titratenew = .2; completenew = .9; noisenew = .5; othernew = .1;
    name = "Basic";
    pdrop = .1;  ptitrate = .2;  pcomplete =.7; pnoise = .9; pother = 1;

    #  THESE HAVE TO BE ASCENDING.  
    w = 10 
    ######################################################################################################################

    patients <- matrix(nrow = p, ncol = s, "NA") #all patients attendance
    invited  <- matrix(nrow = p, ncol = s, 0)  #number of sessions A or S
    missinrow <- matrix(nrow = p, ncol = s, 0) #number of sessions missed in a row
    insess <- vector("numeric", s) #number of people in a session
    set.seed(83877201)
    addlist <- rpois(s, w)

# Set up waitlist
waitlist <- vector("numeric", s)
waitlist[1] <- addlist[1]
for(i in 2:s)
{
 waitlist[i] <- waitlist[i-1] + addlist[i]
}
for (i in 1:p)
{
    for (j in 1:s)
    {  
    if (i < waitlist[j]) patients[i,j] <- "W"
    }
}


#Assign all patients to classes
classlist <- cut(runif(p), c(0, pdrop, ptitrate, pnoise, pcomplete, 1), labels = c("D", "T", "C", "N", "O"))


#First patient
#first session
{
   invited[1,1] <- 1
   insess[1] <- 1
   if (classlist[1] == "D")
   {
      if (runif(1) < dropnew) {patients[1, 1] <- 'A'} else
      {
        patients[1, 1] <- 'S'
        missinrow[1, 1] <- 1
      }
   }
   if (classlist[1] == "T")
   {
        if (runif(1) < titratenew) {patients[1, 1] <- 'A'} else 
        {
          patients[1, 1] <- 'S'
          missinrow[1, 1] <- 1
        }
    }
    if (classlist[1] == "C")
    {
        if (runif(1) < completenew) {patients[1, 1] <- 'A'} else 
        {
        patients[1, 1] <- 'S'
        missinrow[1, 1] <- 1
        }
    }
    if (classlist[1] == "N")
    {
        if (runif(1) < noisenew) {patients[1, 1] <- 'A'} else 
        {
        patients[1, 1] <- 'S'
        missinrow[1, 1] <- 1
        }
    }
    if (classlist[1] == "O")
    {
    if (runif(1) < othernew) {patients[1, 1] <- 'A'} else 
        {
        patients[1, 1] <- 'S'
        missinrow[1, 1] <- 1
        }
    }
}
#Later sessions
for (j in 2 : s)
{
    if (patients[1,(j-1)] == 'A'|patients[1,(j-1)] == 'S')
    {
       invited[1,j] <- invited[1,(j-1)] + 1
    } else
    {
       invited[1,j] <- invited[1,(j-1)]
    }
       if (invited[1,j] <= maxses & missinrow[1,j] < m)
    {
    # Skip or attend
    # If attended previous session    
        if (patients[1, (j-1)] == 'A')
        {
            if (classlist[1] == "D")
            {if (runif(1) < drop) {patients[1, j] <- 'A'} else
                {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- 1
                }
            } 
            if (classlist[1] == "T")
            {if (runif(1) < titrate) {patients[1, j] <- 'A'} else
                {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- 1
                }
            }
            if (classlist[1] == "C")
            {if (runif(1) < complete) {patients[1, j] <- 'A'} else
                {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- 1
                }
            }
            if (classlist[1] == "N")
            {
               if (runif(1) < noise) {patients[1, j] <- 'A'} else 
               {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- 1
               }
            }
            if (classlist[1] == "O")
            {
               if (runif(1) < other) {patients[1, j] <- 'A'} else 
               {
                    patients[1, j] <- 'S'
                    missinrow[1, j] <- 1
                }
            }            
        } else
        # If skipped previous session
        if (patients[1, (j-1)] == 'S')
        {
            if (classlist[1] == "D")
            {
               if (runif(1) < drop) {patients[1, j] <- 'A'} else
               {
                  patients[1, j] <- 'S'
                  missinrow[1, j] <- missinrow[1, (j-1)] + 1
               }
            } 
            if (classlist[1] == "T")
            {
               if (runif(1) < titrate) {patients[1, j] <- 'A'} else
               {
                 patients[1, j] <- 'S'
                 missinrow[1, j] <- missinrow[1, (j-1)] + 1
               }
            }
            if (classlist[1] == "C")
            {if (runif(1) < complete) {patients[1, j] <- 'A'} else
                {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- missinrow[1, (j-1)] + 1
                }
            }
            if (classlist[1] == "N")
            {if (runif(1) < noise) {patients[1, j] <- 'A'} else 
                {
                   patients[1, j] <- 'S'
                   missinrow[1, j] <- missinrow[1, (j-1)] + 1
                }
            }
            if (classlist[1] == "O")
            {
               if (runif(1) < other) {patients[1, j] <- 'A'} else 
               {
                    patients[1, j] <- 'S'
                    missinrow[1, j] <- missinrow[1, (j-1)] + 1
               }
            }            
        }
    } else {patients[1,j] <- 'D'}   
    # check for number of attended or missed sessions
    if (patients[1,(j-1)] == 'A' | patients[1,(j-1)] == 'S')
    {
        insess[j] <- 1
    }   else
    {
        insess[j] <- 0
    }
}


#Second patients
#Patient is waiting and there is space
  #First session
if (insess[1] < maxses & waitlist[1] > 0)  #THIS MAY NEED TO BE A WHILE LOOP, FOR MULTIPLE PATIENTS
{
   invited[2,1] <- 1
   insess[1] <- insess[1] + 1
   if (classlist[2] == "D")
   {
      if (runif(1) < dropnew) {patients[1, 1] <- 'A'} else
      {
        patients[2, 1] <- 'S'
        missinrow[2, 1] <- 1
      }
   }
   if (classlist[2] == "T")
   {
        if (runif(1) < titratenew) {patients[2, 1] <- 'A'} else 
        {
          patients[2, 1] <- 'S'
          missinrow[2, 1] <- 1
        }
    }
    if (classlist[2] == "C")
    {
        if (runif(1) < completenew) {patients[2, 1] <- 'A'} else 
        {
        patients[2, 1] <- 'S'
        missinrow[2, 1] <- 1
        }
    }
    if (classlist[2] == "N")
    {
        if (runif(1) < noisenew) {patients[2, 1] <- 'A'} else 
        {
        patients[2, 1] <- 'S'
        missinrow[2, 1] <- 1
        }
    }
    if (classlist[2] == "O")
    {
    if (runif(1) < othernew) {patients[2, 1] <- 'A'} else 
        {
        patients[2, 1] <- 'S'
        missinrow[2, 1] <- 1
        }
    }
}


  #Later sessions


#Patient invited previous session
for (j in 2 : s)
{
    if (patients[2,(j-1)] == 'A'|patients[2,(j-1)] == 'S')
    {
       invited[2,j] <- invited[2,(j-1)] + 1
    } else
    {
       invited[2,j] <- invited[2,(j-1)]
    } 
       if (invited[2,j] <= maxses & missinrow[2,j] < m)
    {
    # Skip or attend
    # If attended previous session    
        if (patients[2, (j-1)] == 'A')
        {
            if (classlist[2] == "D")
            {if (runif(1) < drop) {patients[2, j] <- 'A'} else
                {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- 1
                }
            } 
            if (classlist[2] == "T")
            {if (runif(1) < titrate) {patients[2, j] <- 'A'} else
                {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- 1
                }
            }
            if (classlist[2] == "C")
            {if (runif(1) < complete) {patients[2, j] <- 'A'} else
                {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- 1
                }
            }
            if (classlist[2] == "N")
            {
               if (runif(1) < noise) {patients[2, j] <- 'A'} else 
               {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- 1
               }
            }
            if (classlist[2] == "O")
            {
               if (runif(1) < other) {patients[2, j] <- 'A'} else 
               {
                    patients[2, j] <- 'S'
                    missinrow[2, j] <- 1
                }
            }            
        } else
        # If skipped previous session
        if (patients[2, (j-1)] == 'S')
        {
            if (classlist[2] == "D")
            {
               if (runif(1) < drop) {patients[2, j] <- 'A'} else
               {
                  patients[2, j] <- 'S'
                  missinrow[2, j] <- missinrow[2, (j-1)] + 1
               }
            } 
            if (classlist[2] == "T")
            {
               if (runif(1) < titrate) {patients[2, j] <- 'A'} else
               {
                 patients[2, j] <- 'S'
                 missinrow[2, j] <- missinrow[2, (j-1)] + 1
               }
            }
            if (classlist[2] == "C")
            {if (runif(1) < complete) {patients[2, j] <- 'A'} else
                {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- missinrow[2, (j-1)] + 1
                }
            }
            if (classlist[2] == "N")
            {if (runif(1) < noise) {patients[2, j] <- 'A'} else 
                {
                   patients[2, j] <- 'S'
                   missinrow[2, j] <- missinrow[2, (j-1)] + 1
                }
            }
            if (classlist[2] == "O")
            {
               if (runif(1) < other) {patients[2, j] <- 'A'} else 
               {
                    patients[2, j] <- 'S'
                    missinrow[2, j] <- missinrow[2, (j-1)] + 1
               }
            }            
        }
    } else {patients[2,j] <- 'D'}   
    # check for number of attended or missed sessions
    if (patients[2,(j-1)] == 'A' | patients[2,(j-1)] == 'S')
    {
        insess[j] <- insess[j] + 1
    }   else
    {
        insess[j] <- insess[j]
    }
}

更新了附加信息 谢谢,约书亚,到目前为止你的帮助。

约书亚要求提供更多信息,以便能够进一步提供帮助。

总体问题是创建参加不同疗程的患者数据集。他们是否参加取决于许多参数,包括他们是否参加了上一次会议(在patients中),他们是什么“类别”(在classlist中),如何他们已经参加或跳过的许多会话(invited)以及他们错过了多少次会议(missinrow);所有这些都会有所不同。如果前一个疗程不满,则会有其他患者被分配到新会话(假设有人在等待(waitlist)。

当我一次这样做一个病人时,效果很好。但当我试图循环所有患者时,我遇到了

您好

这是大型计划的一部分。我无法弄清楚为什么它不起作用,因为我认为它会。代码是

for(i in 2:p)
{  
   while (insess[1] < maxses & waitlist[1] > 0)  
   {
      invited[i,1] <- 1
      waitlist[1] <- waitlist[1] - 1
      insess[1] <- insess[1] + 1
      if (classlist[i] == "D")
      {
         if (runif(1) < dropnew) {patients[i, 1] <- 'A'} else
         {
           patients[i, 1] <- 'S'
           missinrow[i, 1] <- 1
         }
      }
      if (classlist[i] == "T")
      {
           if (runif(1) < titratenew) {patients[i, 1] <- 'A'} else 
           {
             patients[i, 1] <- 'S'
             missinrow[i, 1] <- 1
           }
       }
       if (classlist[i] == "C")
       {
           if (runif(1) < completenew) {patients[i, 1] <- 'A'} else 
           {
           patients[i, 1] <- 'S'
           missinrow[i, 1] <- 1
           }
       }
       if (classlist[i] == "N")
       {
           if (runif(1) < noisenew) {patients[i, 1] <- 'A'} else 
           {
           patients[i, 1] <- 'S'
           missinrow[i, 1] <- 1
           }
       }
       if (classlist[i] == "O")
       {
       if (runif(1) < othernew) {patients[i, 1] <- 'A'} else 
           {
           patients[i, 1] <- 'S'
           missinrow[i, 1] <- 1
           }
       }
   }
}

当我运行时,我转到30(这是正确的),insess [1]转到10(也正确),waitlist [1]转到0(也正确)但患者矩阵仅更新为i = 2.我还检查了班级列表是否有适当的值。

我看不到离开循环的地方。我认为我正在使用错误,但不确定如何。

谢谢!

1 个答案:

答案 0 :(得分:5)

您没有在for循环的每次迭代中重置insess[1]waitlist[1]。在i = 3insess[1] = 10waitlist[1] = 0时,while循环中没有任何内容被执行。

作为附加奖励,这里是使用switch函数的更简洁的代码版本。

for(i in 2:p)
{
   insess[1] <- INITME
   waitlist[1] <- INITMETOO

   while (insess[1] < maxses & waitlist[1] > 0)  
   {
      invited[i,1] <- 1
      waitlist[1] <- waitlist[1] - 1
      insess[1] <- insess[1] + 1

      newswitch <-
        switch(classlist[i],
               D = dropnew,
               T = titratenew,
               C = completenew,
               N = noisenew,
               O = othernew)

      if (runif(1) < newswitch) {
        patients[i, 1] <- 'A'
      } else {
        patients[i, 1] <- 'S'
        missinrow[i, 1] <- 1
      }
   }
}