2013-05-05 141 views
3

我有一個包含這樣的一個數據集:歐氏距離

case,group,val1,val2,val3,val4 
1,1,3,5,6,8 
2,1,2,7,5,4 
3,2,1,3,6,8 
4,2,5,4,3,7 
5,1,8,6,5,3 

我試圖計算編程值的組中的向量之間的歐幾里得距離。

這意味着我在n個組中有x個個案。歐幾里德距離是在行對之間計算的,然後對該組進行平均。所以,在上面的例子中,首先我計算組1的平均值和標準偏差(情況1,2和5),然後標準化值(即[(原始值 - 平均值)/ st dev],然後計算情況之間的ED 1和案例2,案例2和5,案例1和5,最後取平均ED的組。

任何人都可以表明,在一個合理有效的方式實現這一目標的一種巧妙的方法?

回答

1

作爲我將如何處理這在SPSS一個示例中,第一允許讀出的示例性數據到SPSS。

data list list (",")/case group val1 val2 val3 val4 (6F1.0). 
begin data 
1,1,3,5,6,8 
2,1,2,7,5,4 
3,2,1,3,6,8 
4,2,5,4,3,7 
5,1,8,6,5,3 
end data. 
dataset name orig. 

然後我們可以使用SPLIT FILEPROXIMITIES按組,讓我們的距離矩陣。請注意,正如您在flodel答案的評論中提到的那樣,這會產生需要處理的單獨數據集(另請注意,SPSS語法中實際上從不重要,例如split fileSPLIT FILE等效)。

sort cases by group. 
split file by group. 
dataset declare dist. 
PROXIMITIES val1, val2, val3, val4 
/STANDARDIZE = Z 
/MEASURE = EUCLID 
/PRINT = NONE 
/MATRIX = OUT('dist'). 

不同於R,一個SPSS數據矩陣內基本上一切都像的R data.frame,附近以便SPLIT文件功能替換所有不同*ply功能R.非常convienant,但一般不太靈活。所以現在我們需要彙總我保存結果的dist文件中的距離。我們首先對行進行求和,然後通過AGGREGATE命令進行求和。

dataset activate dist. 
compute dist_sum = SUM(VAR1 to VAR3). 
*it appears SPSS keeps empty cases - we dont want them in the aggregation. 
select if MISSING(dist_sum) = 0. 
dataset activate dist. 
DATASET DECLARE dist_agg. 
AGGREGATE 
    /OUTFILE='dist_agg' 
    /BREAK=group 
    /dist_sum = SUM(dist_sum) 
    /N_Cases=N. 
dataset activate dist_agg. 
compute mean_dist = dist_sum /(N_Cases*(N_Cases - 1)). 

這裏我將彙總結果保存到名爲dist_agg的另一個數據集中。因爲SPSS(令人討厭地)保存了全距離矩陣,所以平均值不會是n*(n-1)/2(如等效的R語法),但假設你不想對對數的平均值計算對角元素,那麼將會是n*(n-1)。然後我們可以通過匹配文件命令將這些數據文件合併到orig數據文件中。

*merge back into the original dataset. 
dataset activate orig. 
match files file = * 
/table = 'dist_agg' 
/by group. 
exe. 

*clean out old datasets if you like. 
dataset close dist. 
dataset close dist_agg. 

R的靈活性,來回走matrixdata.frame對象之間,使SPSS這個工作更笨重一點。我可以用SPSS的MATRIX語言編寫更簡潔的程序來完成此任務,但是在MATRIX中的跨組執行操作時會遇到麻煩(與R的*ply語法相比)。

+0

andy-w感謝提供此解決方案與SPSS。我不得不說,我比來自@ flodel的R解決方案更瞭解它,但也許是因爲SPSS(在它的笨拙中)使每個中間步驟都可見!非常感謝您的意見 – lorenzov 2013-05-07 02:45:07

5

是,它可能是R中更容易...

您的數據:

dat <- data.frame(case = 1:5, 
        group = c(1, 1, 2, 2, 1), 
        val1 = c(3, 2, 1, 5, 8), 
        val2 = c(5, 7, 3, 4, 6), 
        val3 = c(6, 5, 6, 3, 5), 
        val4 = c(8, 4, 8, 7, 3)) 

短溶液:

library(plyr) 
ddply(dat[c("group", "val1", "val2", "val3", "val4")], 
     "group", function(x)c(mean.ED = mean(dist(scale(as.matrix(x)))))) 
# group mean.ED 
# 1  1 3.121136 
# 2  2 3.162278 
+0

由於這是輝煌的,但我必須詳細研究的嵌套,因爲我不明白......高興,它的工作,但! – lorenzov 2013-05-05 08:42:27

+0

還有一個問題,我如何確保如果有NA值,該函數也不會返回NA,而是跳過丟失數據的情況? – lorenzov 2013-05-05 08:48:31

+0

查看'mean'函數的'na.rm'參數。 – flodel 2013-05-05 19:16:59

0

這是一個使用base R更簡單的解決方案。

d <- by (dat[,2:5], dat$group, function(x) dist(x)) 

sapply(d,平均)