我在R中搜索一个(简单)函数来删除重复元素,例如unique()
或duplicated()
,它们可以考虑数值的“近似相等”,如all.equal()
:< / p>
unique( c(0, 0))
[1] 0
工作正常,但
unique( c(0, cos(pi/2)) )
[1] 0.000000e+00 6.123032e-17
不会删除第二个元素,尽管与all.equal的比较返回TRUE:
all.equal( 0, cos(pi/2) )
[1] TRUE
同样适用于重复:
duplicated( c(0, cos(pi/2)))
[1] FALSE FALSE
有什么建议吗?谢谢!
答案 0 :(得分:3)
您可能还会考虑zapsmall
功能:
x <- rep(c(1,2), each=5) + rnorm(10)/(10^rep(1:5,2))
unique(x)
# [1] 1.0571484 1.0022854 1.0014347 0.9998829 0.9999985 2.1095720 1.9888208 2.0002687 1.9999723 2.0000078
unique(zapsmall(x, digits=4))
# [1] 1.0571 1.0023 1.0014 0.9999 1.0000 2.1096 1.9888 2.0003 2.0000
unique(zapsmall(x, digits=2))
# [1] 1.06 1.00 2.11 1.99 2.00
unique(zapsmall(x, digits=0))
# [1] 1 2
答案 1 :(得分:2)
如果您想考虑绝对误差,而不考虑相对误差(如all.equal
那样),请尝试:
x <- c(0, cos(pi/2), 1, 1+1e-16)
unique(x)
## [1] 0.000000e+00 6.123234e-17 1.000000e+00
(x <- x[!duplicated(round(x, 10))])
## [1] 0 1
这里我们删除w.r.t相同的元素。一个固定的(10以上)十进制数字。
答案 2 :(得分:0)
您可以尝试使用此代码(免责声明:来自我的软件包cgwtools
)
approxeq <- function (x, y, tolerance = .Machine$double.eps^0.5, ...)
{
if (length(x) != length(y))
warning("x,y lengths differ. Will recycle.")
checkit <- abs(x - y) < tolerance
return(invisible(checkit))
}