Aliya Sarmanova
Aliya Sarmanova

Reputation: 1

loop ifelse for multiple data frames

I want to create a loop to repeat code lines in a list of datasets. Each dataset looks like:

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

So I would like to create a new column and check frequencies in a new column in each dataset.I did it before like this

  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) 

but realised that it might not very efficient. Could you please help me to create a loop as my loop doesn't work ("Error: $ operator is invalid for atomic vectors"):

 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)
 }

Upvotes: 0

Views: 237

Answers (1)

Andre Elrico
Andre Elrico

Reputation: 11480

Try this:

set up data:

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

code:

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

result:

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

  • put all your data.frames into a list (like l1)
  • use lapply

already: ~ 15 times faster than ifelse

#> 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

Upvotes: 1

Related Questions