我正在尝试使用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
足以说出为什么会这样?我有什么办法可以让它适用于我的数据吗?
答案 0 :(得分:3)
失败的近因是irwa.build
使用快速奇异值分解,它只返回矩阵的正奇异值,如?fast.svd
中所述。在您的数据中,唯一值为零,这不是正数,因此您必须使用纯svd
代替fast.svd
。
我创建了一个修补函数sva.patched
,它会稍微修补irwa.build
和sva
函数来处理这种外部情况。我基本上改变了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(sva
)on the Bioconductor mailing list的作者回复:
这个问题很可能是因为基因/特征数量很少 你正在考虑(453)和反应的高维度 变量(12)。有这么多不同级别的响应变量, 许多功能可能与响应显着相关。 sva算法中的部分迭代是减重功能 与响应密切相关,因此整个数据集正在进行中 降低到0。
我建议只运行一次sva迭代。通常需要一个 收集的迭代次数非常少,而且数据也是如此 特征数量相对较低,这可能是 如果你正在进行人工制品发现,那么你可以做的最好。