Звучит как подходящая проблема для рекурсии: определить функцию, которая будет кластеризовать элементы в своем аргументе; если из кластеризации не осталось ни одного элемента, возвращающего элементы, в противном случае вызывайте себя, используя только те элементы, которые все еще присутствуют, и так далее, пока не останется ни одного элемента.
cluster_until_none_left_out = function( elements ) {
aa=cluster(data[elements])
if (sum(aa$colors==0)==0) { return( list(aa,elements) ) }
else{ return( cluster_until_none_left_out(elements[aa$colors!=0]) ) }
}
Немного сложно предоставить полный работающий пример без каких-либо реальных данных, но вот очень простой пример, использующий фиктивные данные, состоящие из вектора случайных целых чисел, которые имитирующая функция «кластеризации» разбивает. на те, которые больше половины среднего (одиночный «кластер»), и те, которые меньше этого (оставленные, «некластеризованные» элементы).
data=sample(1:100)
cluster = function(vec) {
answer=data.frame(vec)
answer$colors=ifelse(vec>mean(vec)/2,1,0)
return(answer)
}
sum(cluster(data)==0)
# shows that one round of clustering leaves some elements in cluster 0
initial_elements=1:100
clustering_elements=cluster_until_none_left_out(initial_elements)[[2]]
sum(cluster(data[clustering_elements])==0)
# 0 (now nobody left in cluster 0)
Теперь выполняется окончательная кластеризация возвращается вместе с индексами используемых элементов. Остальные элементы (кластер 0) - это все остальные.
cluster_0 = initial_elements[ -clustering_elements ]