2010-11-28 2 views
2

У меня есть матрица (размер: 28 столбцов и 47 строк) с числами. Эта матрица имеет дополнительную строку, содержащую заголовки столбцов («порядковые» и «номинальные»).реализация функции расстояния Gower

Я хочу использовать функцию расстояния Gower на этой матрице. Here говорит, что:

Окончательное несходство между Ith и JTH единицами получают в виде взвешенной суммы несходства для каждого переменного:

d(i,j) = sum_k(delta_ijk * d_ijk)/sum_k(delta_ijk) 

В частности, d_ijk представляет собой расстояние между г-ем и -й единица вычисляется с учетом k-й переменной. Это зависит от природы переменного:

  • фактора или символьные столбцы являются рассматриваться как категорные номинальные переменными и d_ijk = 0, если

    x_ik = x_jk, 1 в противном случае;

  • упорядоченных столбцы рассматриваются как категориальных порядковыми переменные и
    значений заменяются с
    индекса соответствующего положения, r_ik в уровнях факторов. Эти позиции
    индексов (которые отличаются от выхода функции Р ранга) являются
    трансформировали следующим образом

z_ik = (r_ik - 1)/(макс (r_ik) - 1)

Эти новые значения, z_ik, рассматриваются как наблюдения переменной
.

Насколько вес delta_ijk обеспокоен:

  • delta_ijk = 0, если x_ik = Н. или x_jk = Н.А.;
  • delta_ijk = 1 во всех других случаях.

Я знаю, что есть функция gower.dist, но я должен сделать это таким образом. Итак, для «d_ijk», «delta_ijk» и «z_ik» я пытался создавать функции, поскольку я не нашел лучшего способа.

Я начал с "delta_ijk" и я попытался это:

Delta=function(i,j){for (i in 1:28){for (j in 1:47){ 
+{if (MyHeader[i,j]=="nominal") 
+ result=0 
+{else if (MyHeader[i,j]=="ordinal") result=1}}}} 
+;result} 

Но я получил ошибку. Поэтому я застрял, и я не могу сделать все остальное.

P.S. Извините, если я ошибаюсь, но английский язык мне не очень часто.

+1

вы можете перенаправить свои данные в виде zip или tar.gz-файла. Мой linux box не откроет архивы rar без меня, чтобы узнать, какое приложение их откроет. Я был бы рад взглянуть, если вы это сделаете. – 2010-11-29 12:11:07

ответ

0

Я не уверен, что твоя логика делает, но ты ставишь слишком много «{« там для твоей собственной пользы ».Я вообще использовать {} пар, чтобы окружать последующее придаточного:

Delta=function(i,j){for (i in 1:28) {for (j in 1:47){ 
     if (MyHeader[i,j]=="nominal") { 
     result=0 
    # the "{" in the next line before else was sabotaging your efforts 
     } else if (MyHeader[i,j]=="ordinal") { result=1} } 
     result} 
        } 
3

Почему вы хотите, чтобы изобретать колесо billyt? В R есть несколько функций/пакетов, которые будут вычислять это для вас, включая daisy() в кластере пакетов, который поставляется вместе с R.

Прежде всего, прежде всего, сначала извлеките эти «данные типа» из ваших данных. Если это действительно матрица, тогда символьная информация в этой строке заголовка сделает всю матрицу символьной матрицей. Если это кадр данных, то все столбцы, вероятно, будут факторами. То, что вы хотите сделать, - это код типа данных в каждом столбце (компонент вашего фрейма данных) как 'factor' или 'ordered'.

df <- data.frame(A = c("ordinal",1:3), B = c("nominal","A","B","A"), 
       C = c("nominal",1,2,1)) 

Что дает это --- обратите внимание, что все они хранятся в качестве факторов из-за дополнительной информации.

> head(df) 
     A  B  C 
1 ordinal nominal nominal 
2  1  A  1 
3  2  B  2 
4  3  A  1 
> str(df) 
'data.frame': 4 obs. of 3 variables: 
$ A: Factor w/ 4 levels "1","2","3","ordinal": 4 1 2 3 
$ B: Factor w/ 3 levels "A","B","nominal": 3 1 2 1 
$ C: Factor w/ 3 levels "1","2","nominal": 3 1 2 1 

Если мы избавимся от первой строки и Recode в правильные типы, мы можем вычислить коэффициент Гоуэр в легко.

> headers <- df[1,] 
> df <- df[-1,] 
> DF <- transform(df, A = ordered(A), B = factor(B), C = factor(C)) 
> ## We've previously shown you how to do this (above line) for lots of columns! 
> str(DF) 
'data.frame': 3 obs. of 3 variables: 
$ A: Ord.factor w/ 3 levels "1"<"2"<"3": 1 2 3 
$ B: Factor w/ 2 levels "A","B": 1 2 1 
$ C: Factor w/ 2 levels "1","2": 1 2 1 
> require(cluster) 
> daisy(DF) 
Dissimilarities : 
      2   3 
3 0.8333333   
4 0.3333333 0.8333333 

Metric : mixed ; Types = O, N, N 
Number of objects : 3 

Что дает такой же, как gower.dist() для этих данных (хотя и в несколько ином формате (as.matrix(daisy(DF))) будет эквивалентно):

> gower.dist(DF) 
      [,1]  [,2]  [,3] 
[1,] 0.0000000 0.8333333 0.3333333 
[2,] 0.8333333 0.0000000 0.8333333 
[3,] 0.3333333 0.8333333 0.0000000 

Вы говорите, что вы не можете сделать это таким образом? Можете ли вы объяснить, почему нет? Как вы, кажется, собираетесь в какой-то степени сделать что-то, что другие люди уже закодировали для вас. Это не домашнее задание, не так ли?

+0

Прежде всего, спасибо Гавину и Двину за ответ. Я использовал функцию «gower.dist», и я также использовал функцию «daisy()», хотя мне не понравилось второе, потому что она сделала все переменные числовыми, и я получил разные результаты с каждой функцией. Я знаю, что то, что я пытаюсь сделать, это повторить то, что уже сделано, но я не могу сделать иначе. Это для исследования, и я должен это сделать, используя R. – billyt 2010-11-29 09:46:45

0

Спасибо, Гэвин и DWin за вашу помощь. Мне удалось решить проблему и найти нужную матрицу расстояния. Я использовал daisy() после того, как перекодировал класс данных, и это сработало.

P.S. Решение, которое вы предложили по моей другой теме для изменения класса столбцов:

DF$nominal <- as.factor(DF$nominal) 
DF$ordinal <- as.ordered(DF$ordinal) 

не работал. Он изменил только первую номинальную и порядковую колонку.

Еще раз спасибо за помощь.

Смежные вопросы