代理变量分析失败,“下标越界”

时间:2012-06-28 20:54:07

标签: r bioconductor

我正在尝试使用Bioconductor's sva package应用代理变量分析。 the vignette中的示例工作正常,但当我使用真实数据进行尝试时,我在irwsva.build中得到了“下标越界”错误:

$ R

R version 2.15.0 (2012-03-30)
…
> trainData <- read.table('http://www.broadinstitute.org/~ljosa/svaproblem/trainData.txt')
> trainpheno <- read.table('http://www.broadinstitute.org/~ljosa/svaproblem/trainpheno.txt')
> testData <- read.table('http://www.broadinstitute.org/~ljosa/svaproblem/testData.txt')
> trainData <- as.matrix(trainData)
> testData <- as.matrix(testData)
> library(sva)
> trainMod <- model.matrix(~as.factor(label), trainpheno)
> num.sv(trainData, trainMod)
[1] 8
> trainMod0 <- model.matrix(~1, trainpheno)
> trainSv <- sva(trainData, trainMod, trainMod0)
Number of significant surrogate variables is:  8 
Iteration (out of 5 ):1  2  3  4  5  Error in irwsva.build(dat = dat, mod = mod, mod0 = mod0, n.sv = n.sv,  : 
  subscript out of bounds

尝试使用debug()缩小范围时,显示{45} x 100矩阵全部为零fast.svd。 (尺寸453 x 100与我的训练集相同。)这导致V为100 x 0; “下标越界”错误是因为irwsva.build尝试索引到V。我的数据一定有一些导致这种行为的东西 - 但是什么?

作为一种可行的解决方法,我尝试使用sva调用method="two-step"

> trainSv <- sva(trainData, trainMod, trainMod0, method='two-step')
Number of significant surrogate variables is:  8 

这很有效,但我需要随后致电fsva。失败是因为使用sva调用method="two-step"导致trainSv$pprob.b为NULL。

那么我的数据与插图中的数据有何不同?两种情况下的训练和测试数据都是矩阵。在小插图中,训练矩阵为22283 x 30;在我的情况下,它是453 x 100.在小插图中,感兴趣的变量(癌症)是二进制的;在我的例子中,因变量可以采用12个不同的值。

最后的差异似乎很重要,因为如果我将范围缩小到[0,7],它就有效:

> trainMod <- model.matrix(~as.factor(label), trainpheno %% 8)
> trainSv <- sva(trainData, trainMod, trainMod0)
Number of significant surrogate variables is:  9 
Iteration (out of 5 ):1  2  3  4  5  > 

考虑到可能有100个样本(列)仅适用于12个类,我尝试了一个包含293列的类似数据集。 (这些数据来自同一个实验,但对293个样本进行了分析,而不是100个处理。)它没有帮助:

> trainData <- read.table('http://www.broadinstitute.org/~ljosa/svaproblem/trainData3.txt')
> trainpheno <- read.table('http://www.broadinstitute.org/~ljosa/svaproblem/trainpheno.txt')
> trainData <- as.matrix(trainData)
> trainMod <- model.matrix(~as.factor(label), trainpheno)
> trainMod0 <- model.matrix(~1, trainpheno)
> trainSv <- sva(trainData, trainMod, trainMod0)
Number of significant surrogate variables is:  11 
Iteration (out of 5 ):1  2  3  4  5  Error in irwsva.build(dat = dat, mod = mod, mod0 = mod0, n.sv = n.sv,  : 
  subscript out of bounds

如果我将sva限制为一次迭代,它可以运行完成,但我不知道我是否可以信任结果:

> trainSv <- sva(trainData, trainMod, trainMod0, B=1)
Number of significant surrogate variables is:  11 
Iteration (out of 1 ):1  > 

有没有人理解irwsva足以说出为什么会这样?我有什么办法可以让它适用于我的数据吗?

2 个答案:

答案 0 :(得分:3)

失败的近因是irwa.build使用快速奇异值分解,它只返回矩阵的奇异值,如?fast.svd中所述。在您的数据中,唯一值为零,这不是正数,因此您必须使用纯svd代替fast.svd

我创建了一个修补函数sva.patched,它会稍微修补irwa.buildsva函数来处理这种外部情况。我基本上改变了irwa.build中的一行:

# Before
sv = fast.svd(dats, tol = 0)$v[, 1:n.sv]
# After
if(any(dats!=0)) sv = fast.svd(dats, tol = 0)$v[, 1:n.sv]
else sv=svd(dats)$v[, 1:n.sv]

您可以选择代码here

但真正的问题是,为什么这些数据最终会产生零值矩阵?我不太了解这种方法,但我可以给你一些线索。

据我所知,您正确使用了这些功能。但是,如果检查循环irwsva.build函数,您将发现如果edge.ldfr函数返回0,它将返回零矩阵。当没有返回p值时,此函数将仅返回零f.pvalue以上,大于0.8。

分解irwa.build,这是从数据开始的方式:

dat=trainData
mod=trainMod
mod0=trainMod0
Id <- diag(ncol(dat))
resid <- dat %*% (Id - mod %*% solve(t(mod) %*% mod) %*% t(mod))
uu <- eigen(t(resid) %*% resid)
# Iterations begin.
mod.b <- cbind(mod, uu$vectors[, 1:n.sv])
mod0.b <- cbind(mod0, uu$vectors[, 1:n.sv])
ptmp <- f.pvalue(dat, mod.b, mod0.b)
which(ptmp>0.8)
# Only one value

现在,第一次进行循环时,只有一个p值高于0.8。通过第二次迭代,没有,这是所有零的原因。

如果在晕影数据上运行相同的代码,您会发现它有许多高于0.8的p值,这就是它不会返回错误的原因。

答案 1 :(得分:0)

John Leek(svaon the Bioconductor mailing list的作者回复:

  

这个问题很可能是因为基因/特征数量很少   你正在考虑(453)和反应的高维度   变量(12)。有这么多不同级别的响应变量,   许多功能可能与响应显着相关。   sva算法中的部分迭代是减重功能   与响应密切相关,因此整个数据集正在进行中   降低到0。

     

我建议只运行一次sva迭代。通常需要一个   收集的迭代次数非常少,而且数据也是如此   特征数量相对较低,这可能是   如果你正在进行人工制品发现,那么你可以做的最好。