Это дополнительный вопрос здесь:
https://stackoverflow.com/a/55912086/3988575
У меня есть такой набор данных:
ID=as.character(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20))
IQ=c(120.5,128.1,126.5,122.5,127.1,129.7,124.2,123.7,121.7,122.3,120.9,122.4,125.7,126.4,128.2,129.1,121.2,128.4,127.6,125.1)
Section=c("A","A","B","B","A","B","B","A","B","A","B","B","A","A","B","B","A","B","B","A")
zz=data.frame(ID,IQ,Section)
zz_new=do.call("rbind", replicate(zz, n=30, simplify = FALSE))
То, что я хотел бы сделать, это сопоставить людей по диапазону их IQ (который был предыдущим вопросом).
Теперь я хочу создать несколько уровней диапазонов. Например, один диапазон может быть 10 IQ-классов: 120-121,121-122,122-123 .... 129-130. Другим примером является один класс IQ: 120-130. Все возможные комбинации вышеперечисленного можно получить:
IQ_Class=c(120,121,122,123,124,125,126,127,128,129,130)
n = length(IQ_Class)-2
all_combin=expand.grid(replicate(n, 0:1, simplify = FALSE))
all_combin$First=1
all_combin$Last=1
all_combin_new=all_combin[c("First",names(all_combin)[1:(length(names(all_combin))-2)],"Last")] #Reorder columns
all_combin_new = t((apply(all_combin_new,1,function(x)(x*IQ_Class)))) #Multiply by IQ classes
all_combin_new = apply(all_combin_new, 1, function(x) { x[x!=0] })
Обратите внимание, что конечный объект all_combin_new предоставляет список списков всех классов (всего 512 классов).
Теперь я хочу взять один класс (один элемент из all_combin_new) и создать все комбинации идентификаторов в этом конкретном классе IQ по их разделам. Сохраните этот набор данных, возьмите следующий класс из all_combin_new и повторите операцию.
Из предыдущего ответа я смог изменить код для рассмотрения комбинаций по разделам, изменив следующее в предыдущем вопросе:
zz1=list("list",length(all_combin_new))
for (i in 1:length(all_combin_new)){ #changed this line to run for all combinations in all_combin_new
zz2=all_combin_new[[i]]
zz11=zz_new%>%
mutate(ID=as.character(ID),vec=as.character(cut(IQ,zz2,right=F)))%>%
group_by(vec,Section)%>% #Changed this line
summarize(if(n()>1)list(data.frame(t(combn(ID,2)),stringsAsFactors = F))
else list(data.frame(X1=ID,X2=ID,stringsAsFactors = F)))%>%
unnest()%>%
bind_cols(read.csv(text=gsub("[^0-9,]","",.$vec),h=F))
zz1[[i]]=as.data.frame(zz11)
}
Мой фактический набор данных имеет около 10K (по сравнению с zz_new здесь) наблюдений с 20 секциями (что приводит к 2 ^ 18 = 262144 диапазонам IQ по сравнению с длиной списка all_combin_new здесь = 512). Это вызывает две основные проблемы:
а) Время: скорость очень низкая. Есть ли способ увеличить скорость?
b) Размер создаваемых объектов: в моих тестах, даже если не считать большое количество комбинаций, списки становятся слишком большими и код не выполняется. Какие альтернативные подходы я мог бы использовать здесь? Обратите внимание, что в списке, который я здесь получаю, мне также необходимо выполнить дальнейшие вычисления.
Любая помощь будет оценена. Заранее спасибо.
P.S. Пожалуйста, дайте мне знать, если какая-то часть неясна или какая-либо часть кода имеет некоторые непреднамеренные ошибки.