2017-08-03 72 views
1

考慮:近似匹配(all.equal的模擬相同)?

(tmp1 <- seq(0, 0.2, 0.01)[16]) 
# [1] 0.15 
(tmp2 <- seq(0, 0.2, 0.05)[4]) 
# [1] 0.15 

identical(tmp1, tmp2) 
# [1] FALSE 
all.equal(tmp1, tmp2) # test for 'near' equality 
[1] TRUE 

的根本原因是floating point precision做。然而,這會導致嘗試使用match識別序列中的子序列的時候出了問題,例如:

match(seq(0, 0.2, 0.05), seq(0, 0.2, 0.01)) 
# [1] 1 6 11 NA 21 

是否有match的替代方案,是爲all.equalidentical模擬?

+3

也許用'round'? 'match(round(tmp2,2),round(tmp1,2))' –

+0

這是個好主意,所以我只需要巧妙地選擇數字參數。 – Alex

+0

@Alex - 'round'絕對適用於矢量。否則就沒用了。 – thelatemail

回答

1

我們可以寫一個自定義的match稱爲near.match,通過dplyr::near啓發:

near.match <- function(x, y, tol = .Machine$double.eps^0.5){ 
    sapply(x, function(i){ 
     res <- which(abs(y - i) < tol, arr.ind = TRUE)[1] 
     if(length(res)) res else NA_integer_ 
    }) 
} 

near.match(seq(0, 0.2, 0.05), seq(0, 0.2, 0.01)) 
# [1] 1 6 11 16 21 
near.match(c(seq(0, 0.2, 0.05), 0.3), seq(0, 0.2, 0.01)) 
# [1] 1 6 11 16 21 NA 
+0

雖然我喜歡這個答案的邏輯(使用'double.eps'),我認爲通過在邏輯中構建'round'可以獲得更高的效率。功能 – Alex

+0

@Alex,我認爲給予tol比較靈活,但缺點是效率較低。 – mt1022