从 Brainerd-Robinson 相似度中排除 0
Excluding 0 from Brainerd-Robinson similarity
我正在使用 Daniel Weidele 中的以下方法来计算一组数据的 Brainerd-Robinson 相似度(代码如下)。我的行代表地点,我的列代表在每个地方发现的人的年龄。我使用相似性来衡量哪些地方彼此具有相似的人口构成,然后我在网络分析中使用输出。
我的问题是,我的很多地方在某些年龄段都有“0”人,因此相似性指数显示这些地方之间存在很强的联系。我想 运行 模型的两次迭代,i) 考虑 '0' 的地方和 ii) 忽略 '0' 的地方,即所以我只是 return 在正数据上生成的索引。
我已经尝试了各种从分析中排除“0”的方法,但到目前为止没有任何效果。对此有什么建议吗?谢谢
# function to load the observations
load = function() {
p <- read.csv("observations.csv")
rownames(p) <- p[,1]
p <- p[,c(2:6)]
return(p)
}
# function to compute the normalized Brainerd-Robinson similarity for observations x
BR <- function(x)
{
rd <- dim(x)[1]
results <- matrix(0,rd,rd)
for (s1 in 1:rd) {
for (s2 in 1:rd) {
results[s1,s2] <- 1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
}
}
rownames(results) <- rownames(x)
colnames(results) <- rownames(x)
return(results)
}
# load observations, compute Brainerd-Robinson similarity and write results to file
write.csv(BR(load()), "br.csv")
为什么不直接问作者呢? :)
当你看行时
results[s1,s2] <- 1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
这主要是魔术发生的地方。让我概述一下这里发生了什么,只看赋值操作的右侧 <-
:
1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
让我们打电话给
- 矢量
x[s1,]
站点 1 的观察 (OOS1),
- 数字(或标量)
sum(x[s1,])
,即 sum(OOS1)
站点 1 的总和(SOS1),
- 和向量
x[s1,] / sum(x[s1,])
站点 1 的标准化观察 (NOS1)
然后我们可以将作业的右侧部分重写为:
1 - (sum(abs(OOS1 / SOS1 - OOS2 / SOS2)))/2
或
1 - (sum(abs(NOS1 - NOS2)))/2
重要的是,NOS1 和 NOS2 仍然是包含每个类别的观测值数量的向量,只是标准化为站点中的比例。
现在是您问题的关键部分:abs(NOS1 - NOS2)
。
NOS1 - NOS2
简单地从一个向量中减去另一个向量。这是您要进行修改的地方,以便不考虑 0 值:
differenceIgnoreZeroes <- function(u, v)
{
# input vectors u and v should have equal length for this to work
result <- vector()
for (i in 1:length(u)) {
if(u[i] == 0 || v[i] == 0) next # SKIP IF EITHER VALUE IS 0
result[i] <- u[i] - v[i]
}
return(result)
}
定义了这个函数,我们就写成differenceIgnoreZeroes(NOS1, NOS2)
而不是NOS1-NOS2
。
我们接下来和之前一样继续取绝对值:
abs(differenceIgnoreZeroes(NOS1, NOS2))
由于生成的向量现在包含 'NA' 个值,因此在对向量求和时我们需要注意不要考虑这些 NA
,否则整个总和将变为 NA
, 也。因此设置参数 na.rm 为 T(rue):
sum(abs(differenceIgnoreZeroes(NOS1,NOS2)), na.rm = T)
因此,我们的总右手赋值如下所示:
1 - (sum(abs(differenceIgnoreZeroes(OOS1 / SOS1, OOS2 / SOS2)), na.rm = T))/2
进一步扩展为
1 - (sum(abs(differenceIgnoreZeroes(x[s1, ] / sum(x[s1,]),
x[s2, ] / sum(x[s2,]))), na.rm = T))/2
希望对您有所帮助!
干杯,
丹尼尔·魏德勒
我正在使用 Daniel Weidele 中的以下方法来计算一组数据的 Brainerd-Robinson 相似度(代码如下)。我的行代表地点,我的列代表在每个地方发现的人的年龄。我使用相似性来衡量哪些地方彼此具有相似的人口构成,然后我在网络分析中使用输出。
我的问题是,我的很多地方在某些年龄段都有“0”人,因此相似性指数显示这些地方之间存在很强的联系。我想 运行 模型的两次迭代,i) 考虑 '0' 的地方和 ii) 忽略 '0' 的地方,即所以我只是 return 在正数据上生成的索引。
我已经尝试了各种从分析中排除“0”的方法,但到目前为止没有任何效果。对此有什么建议吗?谢谢
# function to load the observations
load = function() {
p <- read.csv("observations.csv")
rownames(p) <- p[,1]
p <- p[,c(2:6)]
return(p)
}
# function to compute the normalized Brainerd-Robinson similarity for observations x
BR <- function(x)
{
rd <- dim(x)[1]
results <- matrix(0,rd,rd)
for (s1 in 1:rd) {
for (s2 in 1:rd) {
results[s1,s2] <- 1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
}
}
rownames(results) <- rownames(x)
colnames(results) <- rownames(x)
return(results)
}
# load observations, compute Brainerd-Robinson similarity and write results to file
write.csv(BR(load()), "br.csv")
为什么不直接问作者呢? :)
当你看行时
results[s1,s2] <- 1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
这主要是魔术发生的地方。让我概述一下这里发生了什么,只看赋值操作的右侧 <-
:
1 - (sum(abs(x[s1, ] / sum(x[s1,]) - x[s2, ] / sum(x[s2,]))))/2
让我们打电话给
- 矢量
x[s1,]
站点 1 的观察 (OOS1), - 数字(或标量)
sum(x[s1,])
,即sum(OOS1)
站点 1 的总和(SOS1), - 和向量
x[s1,] / sum(x[s1,])
站点 1 的标准化观察 (NOS1)
然后我们可以将作业的右侧部分重写为:
1 - (sum(abs(OOS1 / SOS1 - OOS2 / SOS2)))/2
或
1 - (sum(abs(NOS1 - NOS2)))/2
重要的是,NOS1 和 NOS2 仍然是包含每个类别的观测值数量的向量,只是标准化为站点中的比例。
现在是您问题的关键部分:abs(NOS1 - NOS2)
。
NOS1 - NOS2
简单地从一个向量中减去另一个向量。这是您要进行修改的地方,以便不考虑 0 值:
differenceIgnoreZeroes <- function(u, v)
{
# input vectors u and v should have equal length for this to work
result <- vector()
for (i in 1:length(u)) {
if(u[i] == 0 || v[i] == 0) next # SKIP IF EITHER VALUE IS 0
result[i] <- u[i] - v[i]
}
return(result)
}
定义了这个函数,我们就写成differenceIgnoreZeroes(NOS1, NOS2)
而不是NOS1-NOS2
。
我们接下来和之前一样继续取绝对值:
abs(differenceIgnoreZeroes(NOS1, NOS2))
由于生成的向量现在包含 'NA' 个值,因此在对向量求和时我们需要注意不要考虑这些 NA
,否则整个总和将变为 NA
, 也。因此设置参数 na.rm 为 T(rue):
sum(abs(differenceIgnoreZeroes(NOS1,NOS2)), na.rm = T)
因此,我们的总右手赋值如下所示:
1 - (sum(abs(differenceIgnoreZeroes(OOS1 / SOS1, OOS2 / SOS2)), na.rm = T))/2
进一步扩展为
1 - (sum(abs(differenceIgnoreZeroes(x[s1, ] / sum(x[s1,]),
x[s2, ] / sum(x[s2,]))), na.rm = T))/2
希望对您有所帮助!
干杯,
丹尼尔·魏德勒