Применение hclust к списку матриц расстояний

Я попытался найти ответ на этот вопрос, но не смог его найти:

Пытаясь выполнить кластеризацию, специфичную для каждого идентификатора пользователя в моем наборе данных (их 385), я вычислил евклидовы расстояния между каждым пользователем и вектор географического расстояния (расстояние гаверсинуса). Однако это привело к списку матриц расстояний, к которому я не могу понять, как применить иерархическую кластеризацию.

Пример

разделение данных по идентификатору пользователя

user_id.split<-split(mydata$geodistancevector,mydata$userid)

вычисление евклидова расстояния для каждого раскола

split.distances<-lapply(user_id.split,function(x) dist(x,method="euclidean"))

str(split.distances) 

приводит к списку из 385, например

    >$ 1  :Class 'dist'  atomic [1:496] 1788.4 24.7 922.2 277.8 873.7 ...
    >.. ..- attr(*, "Size")= int 32
    >.. ..- attr(*, "Diag")= logi FALSE
    >.. ..- attr(*, "Upper")= logi FALSE
    >.. ..- attr(*, "method")= chr "euclidean"
    >``.. ..- attr(*, "call")= language dist(x = x, method = "euclidean")

    >$ 2  :Class 'dist'  atomic (0) 
     .. ..- attr(*, "Size")= int 0
     .. ..- attr(*, "Diag")= logi FALSE
     .. ..- attr(*, "Upper")= logi FALSE
     .. ..- attr(*, "method")= chr "euclidean"
      .. ..- attr(*, "call")= language dist(x = x, method = "euclidean")

Так далее...

Как применить hclust к этому списку расстояний? Я хотел бы иметь возможность разрезать его на 385 (cutree) и связать его с исходным фреймом данных.

Благодарность!


person I.V    schedule 04.08.2015    source источник
comment
Что-то вроде lapply(lapply(split.distances, hclust), cutree)?   -  person Scott Ritchie    schedule 05.08.2015
comment
Спасибо за ответ! Не могли бы вы быть более конкретными? У меня все еще возникают проблемы с запуском кода (все еще довольно нуб с R). Как я могу вызвать hclust для каждого отдельного элемента расстояния в списке от $1 до $385 и вырезать дерево для каждого отдельного подмножества?   -  person I.V    schedule 11.08.2015


Ответы (1)


Расширяя мой комментарий; функция lapply примет функцию (во втором аргументе) и запустит ее для каждого элемента своего первого аргумента.

Итак, чтобы запустить hclust на элементах с $1 по $385 из split.distances, мы можем просто сделать следующее:

lapply(split.distances, hclust)

Это вернет другой список, где каждый элемент - это hclust от $1 до $385. Итак, чтобы применить функцию cutree, мы можем запустить lapply для результатов:

hclust.results <- lapply(split.distances, hclust)
cutree.results <- lapply(hclust.results, cutree)

В своем комментарии я вкладываю вызовы функций, сокращая приведенное выше до:

lapply(lapply(split.distances, hclust), cutree)
person Scott Ritchie    schedule 10.08.2015
comment
Еще раз спасибо за продолжение! действительно ценю это. Однако, когда я пробую код, упомянутый выше, я получаю сообщение об ошибке: должно быть n ›= 2 объекта для кластеризации, поэтому я все еще не уверен, что я что-то упускаю. - person I.V; 11.08.2015
comment
Похоже, что некоторые из ваших матриц расстояний пусты (см. Элемент 2 в вашем сообщении). - person Scott Ritchie; 12.08.2015
comment
поэтому благодаря вашему полезному ответу я удалил все пустые матрицы расстояний lfull<-split.distances[lapply(split.distances, length) > 0] и сгруппировал список с помощью hclust hclust.results <- lapply(lfull, hclust). Однако я не уверен, как вырезать дерево (разрез) в списке, так как каждый подход, который я пробую, я получаю неверную ошибку «дерево» («простой» компонент). Есть ли способ срезать дерево в списке лафетом? - person I.V; 14.08.2015
comment
Похоже, некоторые из ваших split.distances содержат только один-два элемента. cutree выдаст эту ошибку, если встретит дерево с ‹1 слиянием. - person Scott Ritchie; 14.08.2015