如何在R中的向量中找到一个值与其最接近值之间的差异?
How to find the difference between a value and its closest value in a vector in R?
我有一个如下的矢量:
x= c(1,23,4,15,8,17,21)
对向量中的值进行排序后,我们有:
c(1,4,8,15,17,21,23)
我需要的输出是:
c(3, 3, 4, 2, 2, 2, 2)
其中包含该值与其最接近值之间的差异。
但是如果我想输出不排序,有什么解决办法吗?我需要一个像 c(3,2,3,2,4,2,2) 这样的输出来知道哪个样本在输出中具有最大的价值 table (这里第 5 个值是结果)
你可以用蛮力做到:
x <- c(1, 4, 8, 15, 17, 21, 23)
n <- length(x)
ds <- c(
x[2] - x[1],
sapply(
2:(n - 1),
function(i) min(x[i] - x[i - 1], x[i + 1] - x[i])
),
x[n] - x[n - 1]
)
如果我没理解错的话,你想计算一个向量的成员与其相邻元素之间的最小值。
首先,我们对数据进行排序。
x= sort(c(1,23,4,15,8,17,21))
然后,我们计算与左邻居的差异(第 1 项缺失)和与右邻居的差异(第 2 项缺失)
diffs <- cbind(c(NA,diff(x)),c(diff(x),NA))
所以,现在我们有了每一项左右的差异,现在剩下的就是找到最小的了:
res <- apply(diffs,MARGIN=1, min, na.rm=T)
请注意,虽然此解决方案包含解释,但其他提供的解决方案(特别是@Julius 的 pmin-approach)在性能有问题时可能更快。
d <- diff(sort(x))
pmin(c(d, NA), c(NA, d), na.rm = TRUE)
# [1] 3 3 4 2 2 2 2
你可以试试:
library(dplyr)
x <- sort(x)
pmin(abs(x-lag(x)),abs(x-lead(x)),na.rm=T)
#[1] 3 3 4 2 2 2 2
x-lag(x)
计算与最接近的小数的差,x-lead(x)
与最接近的大数的差。
很好的解决方案。 Julius 似乎是最快的:
library(microbenchmark)
set.seed(1262016)
x <- sample(1e5)
all.equal(heroka, NicE, julius, Ambler)
[1] TRUE
microbenchmark(
julius = {d <- diff(sort(x))
pmin(c(d, NA), c(NA, d), na.rm = TRUE)},
NicE = {x <- sort(x)
pmin(abs(x-lag(x)),abs(x-lead(x)),na.rm=T)},
Heroka = {x= sort(x)
diffs <- cbind(c(NA,diff(x)),c(diff(x),NA))
apply(diffs,MARGIN=1, min, na.rm=T)},
Ambler = {n <- length(x)
ds <- c(
x[2] - x[1],
sapply(
2:(n - 1),
function(i) min(x[i] - x[i - 1], x[i + 1] - x[i])
),
x[n] - x[n - 1]
)}
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# julius 4.167302 5.066164 13.94478 7.967066 10.11920 89.06298 100
# NicE 4.678274 6.804918 13.85149 9.297575 12.45606 83.41032 100
# Heroka 142.107887 176.768431 199.96590 196.269671 221.05851 299.30336 100
# Ambler 268.724129 309.238792 334.66432 329.252146 359.88103 409.38698 100
我有一个如下的矢量:
x= c(1,23,4,15,8,17,21)
对向量中的值进行排序后,我们有:
c(1,4,8,15,17,21,23)
我需要的输出是:
c(3, 3, 4, 2, 2, 2, 2)
其中包含该值与其最接近值之间的差异。
但是如果我想输出不排序,有什么解决办法吗?我需要一个像 c(3,2,3,2,4,2,2) 这样的输出来知道哪个样本在输出中具有最大的价值 table (这里第 5 个值是结果)
你可以用蛮力做到:
x <- c(1, 4, 8, 15, 17, 21, 23)
n <- length(x)
ds <- c(
x[2] - x[1],
sapply(
2:(n - 1),
function(i) min(x[i] - x[i - 1], x[i + 1] - x[i])
),
x[n] - x[n - 1]
)
如果我没理解错的话,你想计算一个向量的成员与其相邻元素之间的最小值。
首先,我们对数据进行排序。
x= sort(c(1,23,4,15,8,17,21))
然后,我们计算与左邻居的差异(第 1 项缺失)和与右邻居的差异(第 2 项缺失)
diffs <- cbind(c(NA,diff(x)),c(diff(x),NA))
所以,现在我们有了每一项左右的差异,现在剩下的就是找到最小的了:
res <- apply(diffs,MARGIN=1, min, na.rm=T)
请注意,虽然此解决方案包含解释,但其他提供的解决方案(特别是@Julius 的 pmin-approach)在性能有问题时可能更快。
d <- diff(sort(x))
pmin(c(d, NA), c(NA, d), na.rm = TRUE)
# [1] 3 3 4 2 2 2 2
你可以试试:
library(dplyr)
x <- sort(x)
pmin(abs(x-lag(x)),abs(x-lead(x)),na.rm=T)
#[1] 3 3 4 2 2 2 2
x-lag(x)
计算与最接近的小数的差,x-lead(x)
与最接近的大数的差。
很好的解决方案。 Julius 似乎是最快的:
library(microbenchmark)
set.seed(1262016)
x <- sample(1e5)
all.equal(heroka, NicE, julius, Ambler)
[1] TRUE
microbenchmark(
julius = {d <- diff(sort(x))
pmin(c(d, NA), c(NA, d), na.rm = TRUE)},
NicE = {x <- sort(x)
pmin(abs(x-lag(x)),abs(x-lead(x)),na.rm=T)},
Heroka = {x= sort(x)
diffs <- cbind(c(NA,diff(x)),c(diff(x),NA))
apply(diffs,MARGIN=1, min, na.rm=T)},
Ambler = {n <- length(x)
ds <- c(
x[2] - x[1],
sapply(
2:(n - 1),
function(i) min(x[i] - x[i - 1], x[i + 1] - x[i])
),
x[n] - x[n - 1]
)}
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# julius 4.167302 5.066164 13.94478 7.967066 10.11920 89.06298 100
# NicE 4.678274 6.804918 13.85149 9.297575 12.45606 83.41032 100
# Heroka 142.107887 176.768431 199.96590 196.269671 221.05851 299.30336 100
# Ambler 268.724129 309.238792 334.66432 329.252146 359.88103 409.38698 100