天天看点

R语言的循环

R语言的for循环支持任何向量(注意,是向量),无论向量是任何模式,如

x <- c(3,4,5)
for (n in x) print(n^2)
           

但是如果,我现在有两个matrix,如下

u <- matrix(seq(1,16),ncol=2);u
v <- matrix(seq(17,28),ncol=2);v
           

我希望通过循环的方式,以每个matrix的两列作为输入做线性拟合, 如下

> lm(u[,1]~u[,2])

Call:
lm(formula = u[, 1] ~ u[, 2])

Coefficients:
(Intercept)       u[, 2]  
         -8            1 
           

于是我想当然:

for (m in c(u,v)){
  lm(m[,1]~m[,2])
}
Error in m[, 1] : incorrect number of dimensions
           

我忘记了

c()

会把所有matrix降成一维,这就很尴尬了。这是因为R不支持对非向量集合的循环操作。如果想实现非向量集合的循环,只能曲线救国,如lapply或get,这里介绍get。

get(): 根据命名在环境中搜索变量
get(x, pos = -1, envir = as.environment(pos), mode = "any",
    inherits = TRUE)
pos, envir: 在哪里搜索,这个太复杂,不好展开
mode:定义搜索的变量类型,如function, numeric等
           

一定要记住

get

,一个非常实用的函数,所以上面的for循环应该作如下改写:

for (m in c("u","v")){
  z <- get(m)
  print(z)

}
           

于是,这解决了我昨天晚上遇到的问题。我打算对3个DESeq2的比较table进行过滤,

res1 <- results(dds, contrast = c("condition","Day1","Day0"),pAdjustMethod="fdr",alpha=0.05)
res2 <- results(dds, contrast = c("condition","Day2","Day0"),pAdjustMethod="fdr",alpha=0.05)
res3 <- results(dds, contrast = c("condition","Day3","Day0"),pAdjustMethod="fdr",alpha=0.05)
           

本来代码长下面这个样子,各种他提示错误:

for (res in c(res1,res2,res3)){
  paste0(res, “SigUp”) <- subset(res, padj < 0.01 & log2FoldChange >0 )
}
           

我需要解决两个问题:

一: 如何在for循环中增加变量名, 使用assign对非局部变量进行读写

二: 还有如何对非向量集合进行循环, 使用get获取变量内容。

所以最后的代码长这个样子:

for (res in c("res1","res2","res3")){
  m = get(res)
  nam <- paste0(res,"SigUpt")
  assign(nam, subset(m, padj < 0.01 & log2FoldChange >0 )) 
}
           

其实可以用list,然后用lapply, 然后分别提取的。

resSigUp <- lapply(list(res1,res2,res3), subset, padj < 0.01 & log2FoldChange >0  )
           

继续阅读