r匹配相似的行
下面我将讨论一些类似的观察结果。我的目标是基于欧几里德距离概念,考虑向量r匹配相似的行,r,match,euclidean-distance,R,Match,Euclidean Distance,下面我将讨论一些类似的观察结果。我的目标是基于欧几里德距离概念,考虑向量{x1,x2,x3,x4}和阈值0.2,识别彼此匹配/相似的行。行之间小于0.2的任何距离都视为相似 Observation Blood x1 x2 x3 x4 1 A 0.01 0.16 0.31 0.46 2 A 0.02 0.17 0.32 0.47 3 A 0.0
{x1,x2,x3,x4}
和阈值0.2,识别彼此匹配/相似的行。行之间小于0.2的任何距离都视为相似
Observation Blood x1 x2 x3 x4
1 A 0.01 0.16 0.31 0.46
2 A 0.02 0.17 0.32 0.47
3 A 0.03 0.18 0.33 0.48
4 B 0.05 0.20 0.35 0.49
5 B 0.06 0.21 0.36 0.50
6 B 0.07 0.22 0.37 0.51
7 AB 0.09 0.24 0.39 0.52
8 AB 0.1 0.25 0.4 0.53
9 AB 0.11 0.26 0.41 0.54
10 O 0.13 0.28 0.43 0.55
11 O 0.14 0.29 0.44 0.56
12 O 0.15 0.3 0.45 0.57
我可以用一个非常笨重的双forloop来实现。我想知道是否有一个有效的方法来实现这一点
预期产量
Observation Blood x1 x2 x3 x4 Match
1 A 0.01 0.16 0.31 0.46 Yes
2 A 0.02 0.17 0.32 0.47 Yes
3 A 0.03 0.18 0.33 0.48 No
4 B 0.05 0.20 0.35 0.49 Yes
5 B 0.06 0.21 0.36 0.50 Yes
6 B 0.07 0.22 0.37 0.51 No
7 AB 0.09 0.24 0.39 0.52 No
8 AB 0.1 0.25 0.4 0.53 Yes
9 AB 0.11 0.26 0.41 0.54 No
10 O 0.13 0.28 0.43 0.55 No
11 O 0.14 0.29 0.44 0.56 Yes
12 O 0.15 0.3 0.45 0.57 Yes
Match Dataset
RowToBeMatched FoundMatches_Bgroup_B FoundMatches_Bgroup_AB FoundMatches_Bgroup_O
1 4 8 11
2 5 NA 12
等等 这里有一种使用
fuzzyjoin::distance\u inner\u join
的方法。连接应该非常快,但我们需要过滤掉具有不同血型值的自匹配和巧合匹配
df %>%
fuzzyjoin::distance_inner_join(df, by = c("x1", "x2", "x3", "x4"),
max_dist = 0.02) %>%
filter(Observation.x != Observation.y,
Blood.x == Blood.y)
输出显示了具有足够相似匹配的所有观察结果:
Observation.x Blood.x x1.x x2.x x3.x x4.x Observation.y Blood.y x1.y x2.y x3.y x4.y
1 1 A 0.01 0.16 0.31 0.46 2 A 0.02 0.17 0.32 0.47
2 2 A 0.02 0.17 0.32 0.47 1 A 0.01 0.16 0.31 0.46
3 2 A 0.02 0.17 0.32 0.47 3 A 0.03 0.18 0.33 0.48
4 3 A 0.03 0.18 0.33 0.48 2 A 0.02 0.17 0.32 0.47
5 4 B 0.05 0.20 0.35 0.49 5 B 0.06 0.21 0.36 0.50
6 5 B 0.06 0.21 0.36 0.50 4 B 0.05 0.20 0.35 0.49
7 8 AB 0.10 0.25 0.40 0.53 9 AB 0.11 0.26 0.41 0.54
8 9 AB 0.11 0.26 0.41 0.54 8 AB 0.10 0.25 0.40 0.53
9 10 O 0.13 0.28 0.43 0.55 11 O 0.14 0.29 0.44 0.56
10 11 O 0.14 0.29 0.44 0.56 10 O 0.13 0.28 0.43 0.55
11 11 O 0.14 0.29 0.44 0.56 12 O 0.15 0.30 0.45 0.57
12 12 O 0.15 0.30 0.45 0.57 11 O 0.14 0.29 0.44 0.56
可以将此输出带回以获得所需格式的输出:
df %>%
fuzzyjoin::distance_inner_join(df, by = c("x1", "x2", "x3", "x4"),
max_dist = 0.02) %>%
filter(Observation.x != Observation.y,
Blood.x == Blood.y) %>%
select(Observation.x, Blood.x) %>%
rename(Observation = Observation.x,
Blood = Blood.x) %>%
mutate(Match = "Yes") %>%
right_join(df) %>%
replace_na(list(Match = "No"))
Joining, by = c("Observation", "Blood")
Observation Blood Match x1 x2 x3 x4
1 1 A Yes 0.01 0.16 0.31 0.46
2 2 A Yes 0.02 0.17 0.32 0.47
3 2 A Yes 0.02 0.17 0.32 0.47
4 3 A Yes 0.03 0.18 0.33 0.48
5 4 B Yes 0.05 0.20 0.35 0.49
6 5 B Yes 0.06 0.21 0.36 0.50
7 6 B No 0.07 0.22 0.37 0.51
8 7 AB No 0.09 0.24 0.39 0.52
9 8 AB Yes 0.10 0.25 0.40 0.53
10 9 AB Yes 0.11 0.26 0.41 0.54
11 10 O Yes 0.13 0.28 0.43 0.55
12 11 O Yes 0.14 0.29 0.44 0.56
13 11 O Yes 0.14 0.29 0.44 0.56
14 12 O Yes 0.15 0.30 0.45 0.57
所以
Match
列只是告诉您在整个数据帧中是否存在匹配?您不关心哪一行匹配,只想知道是否有匹配?就这个问题而言,Blood
列并不重要?(或者你只在同一血型中寻找匹配物吗?)这看起来有点像聚类(hclust
,随便什么),因为如果某个特定的血型组中的观察值与该血型组中的其他血型足够接近,它们就会匹配。人们通常首先使用kmeans
聚类,它包含在Base R中的stats
包中。dbscan
包也很好,但不是参数化的,因此可能不是您想要的。您看过包fuzzyjoin吗?请编辑您的问题以说明更多这方面的信息,因为它听起来像是一个不清楚(或根本不存在)的重要要求在问题的当前措辞中,这是否会识别1:1:1:1匹配,这意味着,对于血型组=A中的每一行,在血型组=B、血型组=AB、血型组=O中至少找到一个匹配?最大距离max_dist
确定匹配的阈值。(我改为0.02,所以有些不匹配。)所以它可以对0、1或多个匹配进行罚款。初始联接在所有血型中查找匹配项,但我包含了一个筛选步骤blood.x==blood.y
,前提是不希望包含不同血型的两个观察值之间的匹配项。