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)的均值和标准偏差,然后标准化值(即 [(原始值 - 均值)/标准偏差],然后计算案例之间的 ED 1 和案例 2、案例 2 和 5、案例 1 和 5,最后平均该组的 ED。

任何人都可以提出一种以合理有效的方式实现这一目标的巧妙方法吗?

4

3 回答 3

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
于 2013-05-05T01:10:35.443 回答
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 FILEandPROXIMITIES来按组获取我们的距离矩阵。请注意,正如您在对弗洛德尔答案的评论中提到的那样,这会产生一个我们需要使用的单独数据集(还要注意大小写在 SPSS 语法中几乎不重要,例如split file并且SPLIT 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 文件几乎在功能上替换了 R 中的所有不同*ply函数。非常方便,但总体上不太灵活。所以现在我们需要在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然后我们可以通过 match files 命令将这些合并回数据文件。

*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 在对象之间来回切换的灵活性matrix使得data.frameSPSS 在这项工作中显得有些笨拙。我可以用 SPSS 的语言编写一个更简洁的程序来执行此MATRIX操作,但是跨组执行此操作很麻烦MATRIX(与 R 的*ply语法相比)。

于 2013-05-06T16:52:07.677 回答
0

这是使用基础 R 的更简单的解决方案。

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

sapply(d,mean)

于 2017-03-23T16:56:40.173 回答