具有不相等向量容差和 ID 的交集
intersection with tolerance of non-equal vectors and ID
我对两个向量之间的匹配值有疑问。
假设我有一个矢量和数据框:
data.frame
value name vector 2
154.0031 A 154.0084
154.0768 B 159.0344
154.2145 C 154.0755
154.4954 D 156.7758
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I
现在我想将向量 2 与数据框中的值进行比较,定义的全局公差(例如 +-0.005)是可调的,并将相应的名称添加到向量 2,所以我得到如下结果:
data.frame
value name vector 2 name
154.0031 A 154.0074 A
154.0768 B 159.0334 G
154.2145 C 154.0755 B
154.4954 D 156.7758 E
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I
我试过intersect()
但是里面没有tolerance的选项?
非常感谢!
这个结果可以通过 outer
、which
和子集来实现。
# calculate distances between elements of each object
# rows are df and columns are vec 2
myDists <- outer(df$value, vec2, FUN=function(x, y) abs(x - y))
# get the values that have less than some given value
# using arr.ind =TRUE returns a matrix with the row and column positions
matches <- which(myDists < 0.05, arr.ind=TRUE)
data.frame(name = df$name[matches[, 1]], value=vec2[matches[, 2]])
name value
1 A 154.0084
2 G 159.0344
3 B 154.0755
4 E 156.7758
请注意,这只会 return vec2 的元素匹配,并且 return df 的所有元素都满足阈值。
要使结果对此稳健,请使用
# get closest matches for each element of vec2
closest <- tapply(matches[,1], list(matches[,2]), min)
# fill in the names.
# NA will appear where there are no obs that meet the threshold.
data.frame(name = df$name[closest][match(as.integer(names(closest)),
seq_along(vec2))], value=vec2)
目前,这个 returns 与上面的结果相同,但是 return 在 df 中没有足够观察的情况下会 return NAs。
数据
如果您以后提出问题,请提供可重现的数据。见下文。
df <- read.table(header=TRUE, text="value name
154.0031 A
154.0768 B
154.2145 C
154.4954 D
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I")
vec2 <- c(154.0084, 159.0344, 154.0755, 156.7758)
我对两个向量之间的匹配值有疑问。 假设我有一个矢量和数据框:
data.frame
value name vector 2
154.0031 A 154.0084
154.0768 B 159.0344
154.2145 C 154.0755
154.4954 D 156.7758
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I
现在我想将向量 2 与数据框中的值进行比较,定义的全局公差(例如 +-0.005)是可调的,并将相应的名称添加到向量 2,所以我得到如下结果:
data.frame
value name vector 2 name
154.0031 A 154.0074 A
154.0768 B 159.0334 G
154.2145 C 154.0755 B
154.4954 D 156.7758 E
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I
我试过intersect()
但是里面没有tolerance的选项?
非常感谢!
这个结果可以通过 outer
、which
和子集来实现。
# calculate distances between elements of each object
# rows are df and columns are vec 2
myDists <- outer(df$value, vec2, FUN=function(x, y) abs(x - y))
# get the values that have less than some given value
# using arr.ind =TRUE returns a matrix with the row and column positions
matches <- which(myDists < 0.05, arr.ind=TRUE)
data.frame(name = df$name[matches[, 1]], value=vec2[matches[, 2]])
name value
1 A 154.0084
2 G 159.0344
3 B 154.0755
4 E 156.7758
请注意,这只会 return vec2 的元素匹配,并且 return df 的所有元素都满足阈值。
要使结果对此稳健,请使用
# get closest matches for each element of vec2
closest <- tapply(matches[,1], list(matches[,2]), min)
# fill in the names.
# NA will appear where there are no obs that meet the threshold.
data.frame(name = df$name[closest][match(as.integer(names(closest)),
seq_along(vec2))], value=vec2)
目前,这个 returns 与上面的结果相同,但是 return 在 df 中没有足够观察的情况下会 return NAs。
数据
如果您以后提出问题,请提供可重现的数据。见下文。
df <- read.table(header=TRUE, text="value name
154.0031 A
154.0768 B
154.2145 C
154.4954 D
156.7731 E
156.8399 F
159.0299 G
159.6555 H
159.9384 I")
vec2 <- c(154.0084, 159.0344, 154.0755, 156.7758)