Reputation: 1
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
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
l1
)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