Прежде всего, извините за длинный пост. Понял, что лучше дать контекст, чтобы получить хорошие ответы (надеюсь!). Некоторое время назад я написал функцию R, которая будет получать все попарные взаимодействия переменных в кадре данных. В то время это работало нормально, но теперь коллега хотел бы, чтобы я сделал это с гораздо большим набором данных. Они не знают, сколько переменных у них будет в итоге, но они предполагают, что примерно 2500-3000. Моя функция ниже слишком медленная для этого (4 минуты для 100 переменных). В нижней части этого поста я включил некоторые моменты времени для различного количества переменных и общего количества взаимодействий. У меня есть результаты вызова Rprof () для запуска 100 функций моей функции, поэтому, если кто-то захочет взглянуть на него, дайте мне знать. Я не хочу делать супер длиннее, чем нужно.
Что я хотел бы знать, так это то, что я могу сделать что-нибудь, чтобы ускорить эту функцию. Я пытался смотреть прямо на glm.fit, но, насколько я понял, для того, чтобы это было полезно, вычисление матриц проектирования и всех других вещей, которые я, честно говоря, не понимаю, должно быть одинаковым для каждой модели. , что не так для моего анализа, хотя, возможно, я ошибаюсь по этому поводу.
Буду очень признателен за любые идеи о том, как сделать это быстрее. Я планирую использовать распараллеливание для запуска анализа в конце, но я не знаю, сколько процессоров у меня будет, но я бы сказал, что это будет не более 8.
Заранее спасибо,
Приветствия
Дэви.
getInteractions2 = function(data, fSNPcol, ccCol)
{
#fSNPcol is the number of the column that contains the first SNP
#ccCol is the number of the column that contains the outcome variable
require(lmtest)
a = data.frame()
snps = names(data)[-1:-(fSNPcol-1)]
names(data)[ccCol] = "PHENOTYPE"
terms = as.data.frame(t(combn(snps,2)))
attach(data)
fit1 = c()
fit2 = c()
pval = c()
for(i in 1:length(terms$V1))
{
fit1 = glm(PHENOTYPE~get(as.character(terms$V1[i]))+get(as.character(terms$V2[i])),family="binomial")
fit2 = glm(PHENOTYPE~get(as.character(terms$V1[i]))+get(as.character(terms$V2[i]))+I(get(as.character(terms$V1[i]))*get(as.character(terms$V2[i]))),family="binomial")
a = lrtest(fit1, fit2)
pval = c(pval, a[2,"Pr(>Chisq)"])
}
detach(data)
results = cbind(terms,pval)
return(results)
}
В таблице ниже приведены результаты system.time для увеличения числа переменных, передаваемых через функцию. n - число, а Ints - количество парных взаимодействий, заданных этим числом переменных.
n Ints user.self sys.self elapsed
time 10 45 1.20 0.00 1.30
time 15 105 3.40 0.00 3.43
time 20 190 6.62 0.00 6.85
...
time 90 4005 178.04 0.07 195.84
time 95 4465 199.97 0.13 218.30
time 100 4950 221.15 0.08 242.18
Некоторый код для воспроизведения фрейма данных на случай, если вы захотите посмотреть тайминги или результаты Rprof (). Пожалуйста, не запускайте это, если ваша машина не работает очень быстро или вы не готовы ждать 15-20 минут.
df = data.frame(paste("sid",1:2000,sep=""),rbinom(2000,1,.5))
gtypes = matrix(nrow=2000, ncol=3000)
gtypes = apply(gtypes,2,function(x){x=sample(0:2, 2000, replace=T);x})
snps = paste("rs", 1000:3999,sep="")
df = cbind(df,gtypes)
names(df) = c("sid", "status", snps)
times = c()
for(i in seq(10,100, by=5)){
if(i==100){Rprof()}
time = system.time((pvals = getInteractions2(df[,1:i], 3, 2)))
print(time)
times = rbind(times, time)
if(i==100){Rprof(NULL)}
}
numI = function(n){return(((n^2)-n)/2)}
timings = cbind(seq(10,100,by=5), sapply(seq(10,100,by=5), numI),times)