【问题标题】:loop ifelse for multiple data frames为多个数据帧循环 ifelse
【发布时间】:2018-11-21 13:43:49
【问题描述】:

我想创建一个循环来重复数据集列表中的代码行。 每个数据集如下所示:

gwas_1 
   ID   p
    1   0.0000005
    2   0.0123474
    ... 
gwas_2 
   ID   p
    1   0.0000055
    2   0.5854587
    ... 

所以我想创建一个新列并检查每个数据集中新列中的频率。我以前这样做过

  data=gwas_1
  data$p_threshold <- ifelse(data$p<0.001, 1, 0)
  table (data$p_threshold)
  data=gwas_2
  data$p_threshold <- ifelse(data$p<0.001, 1, 0)
  table (data$p_threshold) 

但意识到它可能效率不高。您能否帮我创建一个循环,因为我的循环不起作用(“错误:$ 运算符对原子向量无效”):

 list=c("gwas_1, gwas_2, gwas_3")
 for (db in list){
 db$p_threshold <- ifelse(db$p<0.001, 1, 0)
 table (db$p_threshold)
 }

【问题讨论】:

  • 只需使用+(data$p&lt;0.001) 而不是ifelse(data$p&lt;0.001, 1, 0) 会更快
  • 只有几个指针:你的向量list=c("gwas_1, gwas_2, gwas_3") 只有一个元素,即字符串"gwas_1, gwas_2, gwas_3",删除引号" . " 以在list 中包含数据帧。尽量不要使用 list 作为变量名,因为它是 R 中的保留函数名。最后尽可能使用 apply 函数而不是 for 循环

标签: r loops if-statement


【解决方案1】:

试试这个:

设置数据:

set.seed(1337)
tmp <- data.frame(p = runif(100)*.007)
l1  <- list(gwas_1 = tmp, gwas_2 = tmp, gwas_3 = tmp)

代码:

lapply(l1, function(x) table(+(x[["p"]]<0.001)))

结果:

#$gwas_1
#
# 0  1 
#88 12 
#
#$gwas_2
#
# 0  1 
#88 12 
#
#$gwas_3
#
# 0  1 
#88 12 

  • 将所有 data.frames 放入一个列表(如 l1
  • 使用lapply

已经:比 ifelse 快约 15 倍

#> set.seed(1337)
#> tmp<-data.frame(p = runif(99999999)*.007)
#> microbenchmark::microbenchmark(+(tmp[["p"]]<0.001) , ifelse(tmp[["p"]]<0.001, 1, 0), times = 4)
#Unit: milliseconds
#                             expr      min        lq     mean   median       uq      max neval cld
#            +(tmp[["p"]] < 0.001)  463.054  527.4309 1779.396 1440.110 3031.362 3774.312     4  a 
# ifelse(tmp[["p"]] < 0.001, 1, 0) 7071.470 7140.4354 8021.247 7887.672 8902.058 9238.173     4   b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多