在没有循环的情况下在 R 中打印列表(应用)

Print list in R without loops (apply)

我希望这个问题对 R 初学者(比如我)来说是很好的教程。 我习惯于需要循环来操作数据、算法等的编程语言。 然而,R 中的循环很慢,这在大数据的情况下可以看出。 幸运的是,R 提供了内置函数,允许迭代元素并以非常有效的方式进行一些计算。

现在我想在 R 中分析数据时避免循环。所以我已经阅读了有关 lapplyapply 和其他有用的功能。

我想在我的数据的第一列和其他列之间建立关联并打印:样本名称、样本估计值和 p 值很好 table - 一切都没有 for 循环.

我的想法 - 从 stratch 创建假数据:

surv <- c(7.1,8,4,2,0.5,5,6)
geneA_expr <- runif(n = 7, min = 1, max = 30)
geneB_expr <- runif(n = 7, min = 1, max = 30)
geneC_expr <- runif(n = 7, min = 1, max = 30)
my_data <- data.frame(surv, geneA_expr, geneB_expr, geneC_expr)

apply 的相关性测试 - 在 Stack Overflow 和手册中找到它:

md_stat <- apply(my_data[,2:4], 2, cor.test, my_data$surv, method="pearson")

md_stat 是一个列表,现在我想很好地可视化它,但我不知道该怎么做,这对我来说太复杂了,所以我使用了 for 循环

for(i in names(md_stat)){
  cat(i ,md_stat[[i]]$estimate, md_stat[[i]]$p.value, '\n')
}

geneA_expr 0.2517658 0.5860052 
geneB_expr 0.2438112 0.5982849 
geneC_expr 0.8026801 0.02977544

如何用其他内置函数替换上面的for循环?

试试这个

temp <- lapply(seq_along(md_stat), function(i) {
    cat(names(md_stat)[[i]], md_stat[[i]]$estimate, md_stat[[i]]$p.value, '\n')
})

我可以想到 4 种方法供您执行此操作,其中 1 种取决于 purrr 包。

你可以使用一个循环,从 purrr 包中走出来,lapply 和一个递归函数。

library(microbenchmark)
library(purrr)

surv <- c(7.1,8,4,2,0.5,5,6)
geneA_expr <- runif(n = 7, min = 1, max = 30)
geneB_expr <- runif(n = 7, min = 1, max = 30)
geneC_expr <- runif(n = 7, min = 1, max = 30)
my_data <- data.frame(surv, geneA_expr, geneB_expr, geneC_expr)

md_stat <- apply(my_data[,2:4], 2, cor.test, my_data$surv, method="pearson")


md_loop <- function(md_stat) {
  for(i in names(md_stat)){
    cat(i ,md_stat[[i]]$estimate, md_stat[[i]]$p.value, '\n')
  }
}

md_walk <- function(md_stat) {
  walk(names(md_stat), function(i) {
    cat(i ,md_stat[[i]]$estimate, md_stat[[i]]$p.value, '\n')
  })
}

md_apply <- function(md_stat) {
  lapply(names(md_stat), function(i) {
    cat(i[[1]],md_stat[[i[[1]]]]$estimate, md_stat[[i[[1]]]]$p.value, '\n')

  })
}

md_recursive <- function(md_stat) {
  i <- names(md_stat)

  if(length(i) < 1) {
    NULL
  } else {
    cat(i[[1]],md_stat[[i[[1]]]]$estimate, md_stat[[i[[1]]]]$p.value, '\n')
    md_recursive(tail(md_stat, -1))
  }
}

md_speed <- microbenchmark(
  md_loop(md_stat),
  md_walk(md_stat),
  md_apply(md_stat),
  md_recursive(md_stat)
)

速度比较

unlist md_stat 中的每个列表。然后将输出绑定到矩阵中。

do.call(rbind, lapply(md_stat, unlist))