我有一个带数字的矩阵(大小:28列和47行)。此矩阵有一个额外的行,其中包含列的标题(“ordinal”和“nominal”)。
我想在此矩阵上使用Gower距离函数。 Here说:
第i个和第j个单位之间的最终差异是作为每个变量的不相似度的加权和得出的:
d(i,j) = sum_k(delta_ijk * d_ijk ) / sum_k( delta_ijk )
特别地,d_ijk表示考虑第k个变量计算的第i个和第j个单元之间的距离。这取决于变量的性质:
因子或字符列是
被视为绝对名义上的
变量和d_ijk = 0
if
x_ik = x_jk,否则为1;
有序列被视为
分类序数变量和
值被替换为
相应的位置指数,r_ik in
要素水平。这些位置
索引(与...不同)
输出R函数等级为
以下列方式转变
z_ik =(r_ik - 1)/(max(r_ik) - 1)
这些新值z_ik被视为对的观察 区间缩放变量。
就权重delta_ijk而言:
我知道有一个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。对不起,如果我犯错误,但英语不是我经常使用的语言。
答案 0 :(得分:3)
你为什么要重新发明轮子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
如果我们摆脱第一行并重新编码为正确的类型,我们可以轻松计算Gower的系数。
> 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
你说你不能这样做吗?你能解释一下为什么不呢?因为你似乎已经做了一些努力来做其他人已经为你编码的事情。这不是作业,不是吗?
答案 1 :(得分:0)
我不确定你的逻辑是做什么的,但是为了你自己的利益,你在那里放了太多“{”。我通常使用{}对来包围consequent-clause:
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}
}
答案 2 :(得分:0)
感谢Gavin和DWin的帮助。我设法解决了问题并找到了合适的距离矩阵。我在重新编码数据类之后使用了daisy()并且工作正常。
P.S。您在我的其他主题中建议的用于更改列类的解决方案:
DF$nominal <- as.factor(DF$nominal)
DF$ordinal <- as.ordered(DF$ordinal)
没用。它只改变了第一个名义和有序列。
再次感谢您的帮助。