for和ifelse循环的替代方法-确定元素是否位于生成的置信区间内

for和ifelse循环的替代方法-确定元素是否位于生成的置信区间内,r,for-loop,if-statement,confidence-interval,R,For Loop,If Statement,Confidence Interval,我试图重写代码,使其不包含任何for循环或ifelse循环。其目的是根据变量mu和变量cinterval提取包含0和1的矩阵-如果y0在其第95个CI内,并且0 y0在其第95个CI内,则生成1,对于y1也是如此。对于许多模块,y0和y1都将重复此操作 mu包含y0和y1的值;cinterval包含四行: y0的第95个CI下限 y0的第95个上限CI y1的第95个CI下限 y1的第95个上限CI cinterval可编程为具有任意数量的模块: cinterval.fn <- funct

我试图重写代码,使其不包含任何for循环或ifelse循环。其目的是根据变量mu和变量cinterval提取包含0和1的矩阵-如果y0在其第95个CI内,并且0 y0在其第95个CI内,则生成1,对于y1也是如此。对于许多模块,y0和y1都将重复此操作

mu包含y0和y1的值;cinterval包含四行:

  • y0的第95个CI下限
  • y0的第95个上限CI
  • y1的第95个CI下限
  • y1的第95个上限CI
  • cinterval可编程为具有任意数量的模块:

    cinterval.fn <- function(y0y1modules) {
      matrix(c(y0results, y1results) nrow=4, ncol=no.of.modules, byrow=T) #simplified from true code
      rownames(cinterval) <- c("y0 95LCI", "y0 95UCI", "y1 95LCI", "y1 95UCI")
      colnames(cinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
      return(cinterval)
    }
    
    > cinterval
             module.1 module.2  module.3
    y0 95LCI 2.434602 1.784056  1.751713
    y0 95UCI 5.988160 6.519465  6.833455
    y1 95LCI 3.778811 2.681708  2.805293
    y1 95UCI 9.228941 9.716476 10.258412
    
    如果您能为ifelse和ifelse提供更高效的编码帮助,我们将不胜感激!我目前使用2个for和ifeelse循环。

    示例数据:

    cinterval <- data.frame(rbind(c(2.434602,1.784056,1.751713),
                                     c(5.988160,6.519465,6.833455),
                                     c(3.778811,2.681708,2.805293),
                                     c(9.228941,9.716476,10.258412)),
                       row.names = c("y0 L","y0 U","y1 L","y1 U") 
    )
    colnames(cinterval) <- paste0("module.",1:3)
    mu <- c("y0" = 4, "y1" = 8)
    

    cinterval假设您的输入数据是这样创建的:

    mu = c(y0 = 4, y1 = 8)
    
    cinterval <-
        data.frame(names = c("y0", "y0", "y1", "y1"),
                   CI = c("LCI", "UCI", "LCI", "UCI"),
                   module.1 = c(2.434602, 5.988160, 3.778811, 9.228941),
                   module.2 = c(1.784056, 6.519465, 2.681708, 9.716476),
                   module.3 = c(1.751713, 6.833455, 2.805293, 10.258412))
    
    mu=c(y0=4,y1=8)
    
    cinterval我不确定您在多大程度上依赖于数据结构,但我提出了一种不同的方法

    如果用另一种格式构造数据集,则可以轻松地将
    incinterval
    的结果写入其他变量中

    新数据:

    cinterval <-  data.frame(year = c(0, 0, 0, 1, 1, 1),
                   LCI = c(2.434602, 1.784056, 1.751713, 3.778811, 2.681708, 2.805293),
                   UCI = c(5.988160, 6.519465, 6.833455, 9.228941, 9.716476, 10.258412),
                   module = c(1, 2, 3, 1, 2, 3)
                   )
    
    > cinterval
      year      LCI       UCI module
    1    0 2.434602  5.988160      1
    2    0 1.784056  6.519465      2
    3    0 1.751713  6.833455      3
    4    1 3.778811  9.228941      1
    5    1 2.681708  9.716476      2
    6    1 2.805293 10.258412      3
    
    使用
    findInterval
    在行上应用一个简短的
    ifelse
    条件,以获得包含结果的新列:

    cinterval$inCI <- apply(cinterval, 1, 
                            function(x) ifelse(x[1] == 0, findInterval(mu["y0"], x[2:3]), 
                                                          findInterval(mu["y1"], x[2:3]))
                            )
    
    请注意,
    findInterval
    如果
    mu
    值低于CI,则返回0;如果值在CI内,则返回1;如果值高于CI,则返回2


    在处理多年的
    问题时,这可能会变得很麻烦,但如果您愿意,它可以包含尽可能多的
    模块。

    谢谢大家的建议和反馈

    我接受了猿的建议,因为这是最简单的

    代码现在用粗体文本更改为:

    incinterval.fn <- function(cov.xy, mu, n1, dr) {
      cinterval <- cintervaloutput.fn(cov.xy, mu, n1, dr) # Generates matrix with 95% CI values for y0 and y1 after treatment modules (can be any number of modules))
      **incinterval <- rbind(as.numeric(mu["y0"] >= cinterval[1,] & mu["y0"] <= cinterval[2,]),
                            as.numeric(mu["y1"] >= cinterval[3,] & mu["y0"] <= cinterval[4,]))**
      colnames(incinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
      return(incinterval)
    }
    

    incinterval.fn您没有给出一个可重复的示例,但给出了一些类似于.numeric(mu[“y0”]>=cinterval[1,]&mu[“y0”]在R中,增加一个向量是个坏主意。你知道向量的大小,你可以将向量设置为0,只有在需要时才可以更改为1。你能
    dput
    cinterval
    matrix吗?手动编写它非常麻烦。@Ape我解释了我的代码,并给出了涉及的变量和结果的示例。我可以编辑我的帖子,使它更清晰如果你提出建议:)?你的建议似乎与我已有的相似。我想我遗漏了一些东西。@Matthew提供代码来生成数据样本及其描述,而不仅仅是发布它的外观,这是一个很好的实践。这里可以包括
    dput(mu)
    dput(cinterval[,1:3])
    的结果。否则,任何想回答问题的人都必须自己创建数据样本,这是不必要和麻烦的(作为笔记)。感谢您对我的问题的建议,以及我的开场白提示。这项工作做得很完美,比我希望的要好得多!我将你的建议改编为:incinterval=cinterval[1,]&mu[“y0”]=cinterval[3,]&mu[“y0”]不客气。请注意,
    ifelse
    也是矢量化的,因此这也可以完成任务:
    ifelse(mu[“y0”]>=cinterval[1,]&mu[“y0”]
    
    mu = c(y0 = 4, y1 = 8)
    
    cinterval <-
        data.frame(names = c("y0", "y0", "y1", "y1"),
                   CI = c("LCI", "UCI", "LCI", "UCI"),
                   module.1 = c(2.434602, 5.988160, 3.778811, 9.228941),
                   module.2 = c(1.784056, 6.519465, 2.681708, 9.716476),
                   module.3 = c(1.751713, 6.833455, 2.805293, 10.258412))
    
    sapply(seq_along(mu),
         function(y) {
    
              cis  <- cinterval[cinterval[["names"]] == names(mu)[y], -1:-2]
    
             apply(cis, 2, function(ci) {
                  findInterval(mu[y], ci)
              })
    
    })
    
    cinterval <-  data.frame(year = c(0, 0, 0, 1, 1, 1),
                   LCI = c(2.434602, 1.784056, 1.751713, 3.778811, 2.681708, 2.805293),
                   UCI = c(5.988160, 6.519465, 6.833455, 9.228941, 9.716476, 10.258412),
                   module = c(1, 2, 3, 1, 2, 3)
                   )
    
    > cinterval
      year      LCI       UCI module
    1    0 2.434602  5.988160      1
    2    0 1.784056  6.519465      2
    3    0 1.751713  6.833455      3
    4    1 3.778811  9.228941      1
    5    1 2.681708  9.716476      2
    6    1 2.805293 10.258412      3
    
    mu <- c("y0" = 4, "y1" = 8)
    
    cinterval$inCI <- apply(cinterval, 1, 
                            function(x) ifelse(x[1] == 0, findInterval(mu["y0"], x[2:3]), 
                                                          findInterval(mu["y1"], x[2:3]))
                            )
    
      year      LCI       UCI module inCI
    1    0 2.434602  5.988160      1    1
    2    0 1.784056  6.519465      2    1
    3    0 1.751713  6.833455      3    1
    4    1 3.778811  9.228941      1    1
    5    1 2.681708  9.716476      2    1
    6    1 2.805293 10.258412      3    1
    
    incinterval.fn <- function(cov.xy, mu, n1, dr) {
      cinterval <- cintervaloutput.fn(cov.xy, mu, n1, dr) # Generates matrix with 95% CI values for y0 and y1 after treatment modules (can be any number of modules))
      **incinterval <- rbind(as.numeric(mu["y0"] >= cinterval[1,] & mu["y0"] <= cinterval[2,]),
                            as.numeric(mu["y1"] >= cinterval[3,] & mu["y0"] <= cinterval[4,]))**
      colnames(incinterval) <- paste('module', 1:length(cinterval[1,]), sep='.')
      return(incinterval)
    }