我得到了1到4之间的数字数组,但通常它们的最小值和最大值之间的差不超过0.5。每个元素之间的差异不小于.1。我想找到包含至少90%(或其他指定比率)元素的最小边距。
也就是说,给定数组
c(1, 1.9, 2, 2, 2, 2, 2.1, 2.2, 2.3, 2.3)
我希望我的函数返回.4,因为2.3-1.9 = .4 <2.3-1 = 1.3。详细信息:
我尝试构建函数几次,但是它一直变得过于复杂,我想知道是否有一种简单的方法可以实现我从未考虑过的事情。
编辑:它必须能够满足偏斜的分布。自从我不断重构代码以来,我还没有完整的代码示例,但是我会做一些事情并将其发布。
Edit2:我无法提供要馈入函数的数组的任何示例,但这是一个用于生成相似值的函数。只要有效,它就不会落在1到4范围内。
x = round(rbeta(20,5,2)*100)/10
答案 0 :(得分:5)
最简单的方法是通过测试包括90%在内的所有可能范围进行暴力破解。为此,我们计算出有多少个术语,因此可以从哪个索引开始,并计算每个术语的差,然后计算出它们的最小值。
x <- c(1, 1.9, 2, 2, 2, 2, 2.1, 2.2, 2.3, 2.3)
n <- ceiling(length(x)*0.9) # get the number of terms needed to include 90%
k <- 1 : (length(x) - n + 1) # get the possible indices the range can start at
x <- sort(x) # need them sorted...
d <- x[k + n - 1] - x[k] # get the difference starting at each range
min(d) # get the smallest difference
答案 1 :(得分:4)
这是一种方法(与@Aaron的方法相同,除了head
/ tail
而非x[i]
之外):
x = c(1, 1.9, 2, 2, 2, 2, 2.1, 2.2, 2.3, 2.3)
xn= length(x)
# number of elements to drop
n = round(0.1*xn)
# achievable ranges
v = tail(x, n+1) - head(x, n+1)
min(v)
# [1] 0.4
确认x个删除n个元素的子向量确实具有以下范围:
n_up = which.min(v) - 1
n_dn = n-n_up
xs = x[(1 + n_up):(xn - n_dn)]
diff(range(xs))
# [1] 0.4
length(x) - length(xs) == n
# [1] TRUE
在新示例上进行测试:
set.seed(1)
x0 = round(rbeta(20,5,2)*100)/10
x = sort(x0)
xn= length(x)
n = round(0.1*xn)
v = tail(x, n+1) - head(x, n+1)
min(v)
# [1] 4.1
# confirm...
n_up = which.min(v) - 1
n_dn = n-n_up
xs = x[(1 + n_up):(xn - n_dn)]
diff(range(xs))
# [1] 4.1
length(x) - length(xs) == n
# [1] TRUE
部分排序可能就足够了(只是为了获得两端的最高和最低值);参见?sort
。
答案 2 :(得分:1)
这可以通过quantile
解决。
0.05
和0.95
分位数。 x
的值。将此向量称为in_90
。 in_90
的最小值和最大值之间的差。指令的顺序就是这样。
qq <- quantile(x, c(0.05, 0.95))
in_90 <- x[qq[1] <= x & x <= qq[2]]
diff(range(in_90))
#[1] 0.4
功能:
amplitude <- function(x, conf = 0.9){
quants <- c((1 - conf)/2, 1 - (1 - conf)/2)
qq <- quantile(x, quants)
inside <- x[qq[1] <= x & x <= qq[2]]
diff(range(inside))
}
amplitude(x)
#[1] 0.4
数据。
x <- c(1, 1.9, 2, 2, 2, 2, 2.1, 2.2, 2.3, 2.3)