如何通过向量计算?

时间:2016-12-04 18:09:13

标签: r

enter image description here更新:现在它正在运作,但仍然不知道另一种方式如何运作。

 cuts <- seq(from=3, to=36, by=0.01)

    for (i in cuts) {
      cut_off<- i
      set.seed(666)
      samp_h <-rnorm(1000,mean=12,sd=3)
      samp_d <-rnorm(1000,mean=18,sd=6)
      a <- sum(samp_h <= cut_off)
      c <- sum(samp_h > cut_off)
      b <- sum(samp_d <= cut_off)
      d <- sum(samp_d > cut_off)
      sens <- a / (a+c)
      spci <- d / (d+b)
      assign(paste("ss",as.character(cut_off),sep = ""), sens)
      assign(paste("sp",as.character(cut_off),sep = ""), spci)}

    ss_v<- unlist(
      lapply(               
        paste0("ss",cuts), 
        get)              
    )

    sp_v<- unlist(
      lapply(               
        paste0("sp",cuts), 
        get)              
    )

    plot(1-sp_v, ss_v)

大家好:    我试图使用不同的&#39; cut_off&#39;得到不同的感觉&#39; (敏感的)和&#39; spci&#39; (spcificity)。上面代码的问题是,对于34&#39; cut&#39;,我可以得到结果。但如果我将削减更改为:

cuts <- seq(from=3, to=36, by=0.01)

此方法无法返回结果。问题是我计算每个向量中的数字,所以我问如何使用向量来计算&#34; ss_v&#34;和&#34; ss_p&#34;直。非常感谢你。

背景资料: 假设在'健康'患者中,抗体水平分布正常(12,32),而'患病'患者抗体分布正常(18,62)。请注意,这些是“组成”的数字,并不是切合实际的。 模拟大量患病和健康患者的抗体计数(例如每个患者1000个) - 使用R中的'rnorm'功能。如果选择15的截止值,灵敏度和特异性是多少? 记录3到36之间的一系列截止值的灵敏度和特异性(例如3,3.01,3.02,...,35.98,35.99,36)。提示:使用R中的“seq”函数生成截止值,然后使用“for”循环或矢量化计算来计算灵敏度和特异性。 在x轴上生成'1-Specificity',在y轴上生成'Sensitivity'。

1 个答案:

答案 0 :(得分:0)

您的代码是尝试将R用作宏语言的示例。更好的是学习如何正确使用R矢量。由于您使用了for - 循环,因此您应该预先分配sensspci,而是将sensspci指定为索引向量。 (所以我赞同你对结果向量的要求,作为一种明智的方法。)然后给出矢量名称,而不是乱丢你的工作区,大量单独的,断开连接的命名对象。试试这个:

cuts <- seq(from=3, to=36, by=1)
sens <- numeric(length(cuts)); spci=numeric(length(cuts))
for (i in cuts) {
  cut_off<- i
  set.seed(666)
  samp_h <-rnorm(1000,mean=12,sd=3)
  samp_d <-rnorm(1000,mean=18,sd=6)
  hth <- table(samp_h)
  dis <-table(samp_d)
  a<-length(hth[names(hth) <= cut_off])
  c<-length(hth[names(hth) > cut_off])
  b <-length(dis[names(dis) <= cut_off])
  d <-length(dis[names(dis) > cut_off])
  sens[i] <- a / (a+c)
  spci[1] <- d / (d+b)
} 
 names(sens) <- paste0("ss",cuts)  
 names(spci) <- paste0("sp",cuts)

我不认为在每个循环迭代中处理新的模拟数据集的想法确实给我带来了效率,但是如果你用diff来模拟某些东西的话。我也不确定你是否正确构造了sensspci作为敏感性和特异性,但至少你现在可以看到结果是什么样的。有几个包将构建ROC曲线。

这就是我怀疑你的循环算法是否正确的原因:

> sens
  ss3   ss4   ss5   ss6   ss7   ss8   ss9  ss10  ss11  ss12  ss13 
0.000 0.000 0.745 0.747 0.752 0.764 0.792 0.836 0.895 0.000 0.123 
 ss14  ss15  ss16  ss17  ss18  ss19  ss20  ss21  ss22  ss23  ss24 
0.239 0.374 0.485 0.593 0.661 0.700 0.721 0.736 0.744 0.745 0.745 
 ss25  ss26  ss27  ss28  ss29  ss30  ss31  ss32  ss33  ss34  ss35 
0.745 0.745 0.745 0.745 0.745 0.745 0.745 0.747 0.747 0.747 0.747 
 ss36  <NA>  <NA> 
0.747 0.747 0.747 

它看起来不像我期望的灵敏度结果。我可能使用abcd <-table( samp_h >= cut_off, samp_d >= cutoff)之类的代码来生成a,b,c,d的值。然后,您可以对该表结果使用矩阵索引。另一个选项可能是跳过你的表工作并使用这个代码块:

  a <- sum(samp_h <= cut_off)
  c <- sum(samp_h > cut_off)
  b <- sum(samp_d <= cut_off)
  d <- sum(samp_d > cut_off)

sens - itivity结果现在看起来更合理,但不是spci结果。(因为我的索引错误,现在修复了以下代码。)

cuts <- seq(from=3, to=36, by=1)
sens <- numeric(length(cuts)); spci=numeric(length(cuts))
  set.seed(666)
  samp_h <-rnorm(1000,mean=12,sd=3)
  samp_d <-rnorm(1000,mean=18,sd=6)
#Only need to make the test data.frame once
 dfrm <- data.frame( vals = c(samp_h, samp_d), 
                     grp = c( rep("H", 1000), rep("D",1000) ) )

for (i in seq_along(cuts) ) {
  cut_off<- i

  abcd <- with(dfrm, 
    table(Test_res = vals > cut_off, 
          status=grp ) )
  sens[i] <- abcd["TRUE","D"] / sum( abcd[, "D"])
  spci[i] <- abcd["FALSE", "H"] / sum( abcd[, "H"])
} 
 names(sens) <- paste0("ss",cuts)  
 names(spci) <- paste0("sp",cuts)

plot(  1-spci, sens, type="b")
text( 1-spci[c(TRUE,FALSE,FALSE,FALSE,FALSE)]+.05, 
      # hack to print every 5th cutoff value
      sens[c(TRUE,FALSE,FALSE,FALSE,FALSE)], 
      label=(3:36)[ c(TRUE,FALSE,FALSE,FALSE,FALSE)] )

enter image description here