2012-04-11 39 views
8

說,我有一個向量y,我想檢查y中的每個元素是否爲整數,如果不是,則停止並顯示錯誤消息。我試過is.integer(y),但它不起作用。如何檢查矢量中的每個元素是否是R中的整數?

+5

這是一個很難定義一個「整數」究竟是什麼的問題 - 你需要在「整數」和整數數據類型的意義上闡明整數。你很少直接在R中處理數據類型整數(但這就是整數測試) - 請看Martin Maechler在這裏提供的is.whole():https://stat.ethz.ch/pipermail/ r -help/2003-April/032471.html – mweylandt 2012-04-11 21:06:25

+0

當你停下來時,你想知道你停在哪裏......也就是說哪一個不是第一個整數?一個向量只包含一種數據類型。所以,你不能指整數類型,只能是整數。即使這樣也有點問題,因爲不是所有的整數都是完整的整數。你還需要一個完整的數字的偏差容忍。將這些問題的答案添加到您的問題中。 – John 2012-04-11 21:15:21

回答

15

最簡單(最快!)的東西可能是這樣的:

stopifnot(all(y == floor(y))) 

...所以試試看:

y <- c(3,4,9) 
stopifnot(all(y == floor(y))) # OK 

y <- c(3,4.01,9) 
stopifnot(all(y == floor(y))) # ERROR! 

如果你想有一個更好的錯誤消息:

y <- c(3, 9, NaN) 
if (!isTRUE(all(y == floor(y)))) stop("'y' must only contain integer values") 
+0

更新了自定義錯誤消息版本來處理NA/NaN ... – Tommy 2012-04-11 22:34:44

9

你可以這樣做:

y <- c(3,3.1,1,2.3) 
    (y - floor(y)) == 0 
    [1] TRUE FALSE TRUE FALSE 

(y - round(y)) == 0 

,如果你想對整個事情的單一TRUEFALSE,把它放在all(),如:

all((y - round(y)) == 0) 
    [1] FALSE 
+0

每個元素都有一個TRUE/FALSE值,因爲R是矢量化語言。 – Rodrigo 2015-09-02 14:52:22

4

不知道Tim的方式還是這個更快,但是:

> x <- 1:5 
> y <- c(x, 2.0) 
> z <- c(y, 4.5) 
> all.equal(x, as.integer(x)) 
[1] TRUE 
> all.equal(y, as.integer(y)) 
[1] TRUE 
> all.equal(z, as.integer(z)) 
[1] "Mean relative difference: 0.1111111" 
> 

或:

all((z - as.integer(z))==0) 
+0

因爲all.equal(3.00000001,3L)不是真的,所以可以使用'identical()'而不是'all.equal()'。 – BenBarnes 2012-04-11 21:17:33

+0

@BenBarnes'相同(y,as.integer(y))'爲我返回'FALSE',但是,你是對的。減法技術可能是一個更傻的證明... – Justin 2012-04-11 21:36:42

+0

我認爲@mweylandt和@約翰的關於這個問題的含糊不清的評論是正確的(這正是我想要得到的)。當R看到它時,'is.integer(2.0)'爲'FALSE',但爲了其他目的和目的,它是一個很好的整數。 – BenBarnes 2012-04-11 22:08:18

2

我在一個完全不同的方向,然後添去(我喜歡他的更好,雖然我的方法適用於混合向量與整數等字符向量):

int.check <- function(vect) { 
    vect <- as.character(vect) 
    sapply(vect, function(x) all(unlist(strsplit(x, ""))%in% 0:9)) 
} 

x <- c(2.0, 1111,"x", 2.4) 
int.check(x) 

編輯:改變功能,因爲它只對字符向量工作。

這適用於類字符的向量,以及萬一你有一個混合了各種數字的字符向量但被強制轉換爲字符。

+0

...雖然很慢。回答'y <-1:1E5; system.time(int.check(y))'大約需要1.8秒。我的版本需要0。01或更少;-) – Tommy 2012-04-11 22:09:35

+0

哦,是的,如果你有一個數字向量,只是一個不同的採取絕對不是要走的路但請看看你的方法如何工作在'y <-c(1:1e5,「x」)'; ) – 2012-04-11 22:14:07

+0

PS我得到4.12秒,但不是太糟糕。 – 2012-04-11 22:18:34

6

這裏的另一種方式(使用同樣的伎倆,因爲每個數字比較裹挾進「整數」類型的號碼的賈斯汀):

R> v1 = c(1,2,3) 
R> v2 = c(1,2,3.5) 
R> sapply(v1, function(i) i == as.integer(i)) 
[1] TRUE TRUE TRUE 
R> sapply(v2, function(i) i == as.integer(i)) 
[1] TRUE TRUE FALSE 

爲了讓你的測試:

R> all(sapply(v2, function(i) i == as.integer(i))) 
[1] FALSE 
0

如果已經浮點表示錯誤,請嘗試:

round(y, TOLERANCE.DIGITS) %% 1 == 0 

在我的申請,我不得不認真殘酷浮動點代表性錯誤,例如:

> dictionary$beta[3] 
[1] 89 
> floor(dictionary$beta[3]) 
[1] 88 
> as.integer(dictionary$beta)[3] 
[1] 88 
> dictionary$beta[3] %% 1 
[1] 1 

除以1的餘數爲1。我發現在整數之前我必須輪迴。我認爲所有這些測試將失敗的情況下,你想要上述89計爲一個整數。全部。平等」的功能,就是要處理浮點表示錯誤的最好辦法,但:

all.equal(88, 89); 

在我的情況下,將有(也沒有)給出了一個整數值檢查假陰性

編輯:在基準測試中,我發現:

(x == as.integer(x)) 

是普遍的最好表演

(x == floor(x)) 
((x - as.integer(x)) == 0) 

通常運行良好,通常同樣快。

(x %% 1 <= tolerance) 

的作品,但不盡快別人

!(is.character(all.equal(x, as.integer(x)))) 

當載體是不是整數,有可怕性能(當然,因爲它關係到估計差的麻煩)。

identical(x, as.integer(x)) 

當載體是所有整數值,則返回不正確結果(假定的問題是爲了檢查整數值,而不是整數類型)。

1

檢查以下內容可以幫助我們在條件允許的情況下使用腳本。

sff <- 5 

if(!(is.integer(sff) == is.character(sff))){ 
    sff 
} else { 
    "hello" 
} 

hello 

sff <- 'a''a'作爲結果。

+0

你能解釋一下情況在做什麼嗎?我不能。 – eckes 2014-05-07 23:33:31

相關問題