2017-11-13 6 views
1

私は、ケースをグループ化する必要があるプロジェクトに取り組んでいます。私はnpiのデータを持っています。npiのアドレス、電話、名前のような情報があります。 私の目標は、同じグループ内で最も似ているnpiをグループ化することです。私は最初に距離行列を作成し、ケースをまとめてグループ化するしきい値を と決定することでこれを達成したいと考えています。しかし、私は文字列変数のための距離行列を作成する方法の困難に遭遇しています。 基本的に2つの質問があります。文字列と互換性のある特定の特殊な距離行列

最初に、出力として距離行列を作成するデータフレームのケース間の類似性を比較する距離関数を作成する方法はありますか? 同じ変数でより多くの値を共有すればするほど、私はそれらを近づけたいので、距離行列の高い/低いスコアです。

第2に、この距離関数を文字列変数と互換性を持たせるにはどうすればよいですか?

コード:

#sample data 
df <- read.table(text='npi a b c 
      51 6 2 1 
      52 6 2 6 
      53 10 9 2 
      54 7 4 7 
      55 7 10 5 
      56 8 5 7 
      57 7 2 10 
      58 5 9 3 
      59 8 4 6 
      60 1 10 2', header=T, sep='') 

#convert 1st column of data as the row index 
df1 <- df[,-1] 
rownames(df1) <- df[,1] 

#calculate distance 
library('proxy') 
dist_func <- function(x, y) length(intersect(x,y))/3 
proxy::dist(df1, method = dist_func) 

出力:

  51  52  53  54  55  56  57   58  59 
    52 0.6666667                     
    53 0.3333333 0.3333333                  
    54 0.0000000 0.0000000 0.0000000                
    55 0.0000000 0.0000000 0.3333333 0.3333333             
    56 0.0000000 0.0000000 0.0000000 0.3333333 0.6666667           
    57 0.3333333 0.3333333 0.6666667 0.3333333 0.6666667 0.3333333        
    58 0.0000000 0.0000000 0.3333333 0.0000000 0.3333333 0.3333333 0.0000000      
    59 0.3333333 0.3333333 0.0000000 0.3333333 0.0000000 0.3333333 0.0000000 0.0000000   
    60 0.6666667 0.3333333 0.6666667 0.0000000 0.3333333 0.0000000 0.6666667 0.0000000 0.0000000 

質問:xとyとして定義されて何 1?他のすべての行とは対照的に行がありますか? この定義された関数では、距離は変数に固有のものではありません。値が同じ変数に表示される場合は、2つのケースを '交差'させるだけです。 2.変数を特定のものにするために関数に追加する必要があるのは何ですか?

さらに、このメソッドは文字列変数では機能しません。

コード:

#create dataset with strings 
    df2 <- read.table(text='npi dier getal mubilair 
      51 "aap" een tafel 
      52 vis twee stoel 
      53 paard twee zetel 
      54 kip drie fouton 
      55 beer vier fouton 
      56 aap vijf bureau 
      57 tijger zes bank 
      58 zebra zeven sofa 
      59 olifant acht wastafel 
      60 mens acht spiegel', header=T, sep='') 
    #convert 1st column of data as the row index 
    dfstring <- df2[,-1] 
    rownames(dfstring) <- df[,1] 
    #calculate distance 
    library('proxy') 
    dist_func <- function(x, y) length(intersect(x,y))/3 
    proxy::dist(dfstring, method = dist_func) 

出力:

   51  52  53  54  55  56  57  58  59 
    52 0.0000000                     
    53 0.0000000 0.6666667                  
    54 0.6666667 0.0000000 0.0000000                
    55 0.3333333 0.0000000 0.0000000 0.6666667             
    56 0.3333333 0.3333333 0.3333333 0.3333333 0.3333333           
    57 1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.3333333        
    58 0.0000000 0.6666667 0.6666667 0.0000000 0.0000000 0.0000000 0.0000000      
    59 0.3333333 0.3333333 0.0000000 0.0000000 0.3333333 0.3333333 0.3333333 0.3333333   
    60 0.3333333 0.3333333 0.3333333 0.0000000 0.3333333 0.3333333 0.3333333 0.3333333 0.6666667 

この距離行列は 問題が交差するコマンドであるのは意味がありません:

> dfstring[1,] 
     dier getal mubilair 
    51 aap een tafel 
    > dfstring[2,] 
     dier getal mubilair 
    52 vis twee stoel 
    > dfstring[4,] 
     dier getal mubilair 
    54 kip drie fouton 
    > intersect(dfstring[1,], dfstring[2,]) 
    data frame with 0 columns and 0 rows 
    > intersect(dfstring[1,], dfstring[4,]) 
     dier 
    54 kip 

が交差するような機能があります文字列変数も同様に機能しますか?

私の初期関数変数を特定にする方法と、文字列変数と互換性を持たせる方法を教えてください。 xyについて

答えて

1
  1. 、 "行Y" と比較して "行X" 考えます。あなたの関数の最初の呼び出し時にxyの実際の値を見て、

    dist_func <- function(x, y) { 
        browser() 
        length(intersect(x,y))/3 
    } 
    

    ことと、それを実行するために、あなたの関数を変更することが有益かもしれません。

  2. intersectは、ベクトル内の位置については何も知らず、単に「存在」を意味するセットベースであることに注意してください。help pageも、「セット」と題して、あなただけのプレーンな平等のために見ていない、あなたが望む結果を得るために

    Performs *set* union, intersection, ... 
    

    で始まっていますか?

    dist_func <- function(x, y) sum(x == y)/3 
    

    NB:数値(非整数)の数字を見ている場合はtrue平等はR FAQ 7.31ごとに、問題となる可能性があります。

  3. お客様のデータは、ではなくcharacter秒です。もし$getalの最初の値は、要素の内部で整数3である"acht"であること、例えば、

    str(df2) 
    # 'data.frame': 10 obs. of 4 variables: 
    # $ npi  : int 51 52 53 54 55 56 57 58 59 60 
    # $ dier : Factor w/ 9 levels "aap","beer","kip",..: 1 8 6 3 2 1 7 9 5 4 
    # $ getal : Factor w/ 8 levels "acht","drie",..: 3 4 4 2 5 6 7 8 1 1 
    # $ mubilair: Factor w/ 9 levels "bank","bureau",..: 7 6 9 3 3 2 1 4 8 5 
    

    注意に気づくかもしれません。 3つの列の4番目の整数値は3,2,3です(それぞれ、列 "51"と行 "54"の距離メトリック0.667に一致します)。

    read.table(..., stringsAsFactors = FALSE)以下のようなものにするためにあなたの距離関数:

    dist_func2 <- function(x, y) { 
        if (is.factor(x)) x <- as.character(x) 
        if (is.factor(y)) y <- as.character(y) 
        sum(x == y)/3 
    } 
    

    (私は個人的にstringsAsFactorsを提案するが、メーリングリストへ。)

関連する問題