使用all.equal()功能的unique()或duplicated()?

时间:2014-05-22 11:15:25

标签: r

我在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

有什么建议吗?谢谢!

3 个答案:

答案 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))
}