我有一个带有数字的矩阵(大小:28列和47行)。此矩阵有一个额外的行,其中包含各列的标题(“普通”和“标称”)。
我想在此矩阵上使用高尔距离函数。 Here说:
第i个单位和第j个单位之间的最终差异是每个变量的差异的加权总和:
d(i,j) = sum_k(delta_ijk * d_ijk ) / sum_k( delta_ijk )
特别地,d_ijk代表考虑了第k个变量而计算出的第i个与第j个单位之间的距离。这取决于变量的性质:
因素或字符列是
被视为绝对名义
变量和
d_ijk = 0
如果x_ik = x_jk,否则为1;
有序列被视为
分类序数变量和
这些值将替换为
对应的位置索引r_ik
因素水平。这些位置
索引(与
R函数等级的输出)是
按以下方式转换
z_ik =(r_ik-1)/(max(r_ik)-1)
这些新值z_ik被视为对
区间比例变量。
就权重delta_ijk而言:
如果x_ik = NA或x_jk = delta_ijk = 0
NA;
在所有其他情况下,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}
但是我出错了。所以我被卡住了,其余的我都做不了。
附言如果我犯错了,请原谅,但是英语不是我经常使用的语言。
最佳答案
您为什么要重新发明车轮Billyt? R中有几个函数/程序包可以为您计算这些,包括R随附的程序包集群中的daisy()
。
首先,从数据中获取那些“数据类型”标头。如果这确实是一个矩阵,则此标题行中的字符信息将使整个矩阵成为字符矩阵。如果是数据帧,则所有列都可能是因素。您要做的是将每列(数据框的组成部分)中的数据类型编码为'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
如果我们摆脱了第一行并重新编码为正确的类型,则可以轻松计算高尔系数。
> 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
你说你不能这样吗?你能解释为什么不吗?正如您似乎将在某种程度上努力去做别人已经为您编写的代码。这不是功课,对吗?