Extract only integers from a vector

I have a question about picking specific values ​​from a vector in R. Specifically, I want to select all integer values ​​from a given variable in my dataset (I want to use them for a subset of my data). Here's an example:

x <- seq(0,10,1/3)

      

Now I want to select all the observations in the vector x with integers. My first idea was to use a command is.integer

, but that didn't work. I found a workaround solution using the following:

> x==as.integer(x)
 [1]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
FALSE TRUE FALSE FALSE  TRUE
[17]  FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE 
FALSE  TRUE FALSE FALSE  TRUE

      

Now I can just type

> which(x==as.integer(x))
 [1]  1  4  7 10 13 16 19 22 25 28 31

      

and I am getting the expected result (and I can use this vector for a subset of my dataset). But isn't there a more direct way to select integer values?

+3


source to share


2 answers


While your solution is already a good one, here's another way to do it, summarizing all the comments that came up from your question:

x <- seq(0, 10, 1/3)

# selecting elements of x for which the rest of the eucliean division (by 1) is not 0
x[!x%%1] 
#[1]  0  1  2  3  4  5  6  7  8  9 10

      

NB: due to the way repositories are stored, this answer (and your solution as well) can sometimes fail, see @ BondedDust's answer

For everything to be fine, we need to add a "response" to the answer, which leads to a more complex but always accurate answer:



tol <- 1e-12
x[sapply(x, function(y) min(abs(c(y%%1, y%%1-1))) < tol)]

      

with BondedDust example

x <-  seq(1/3, 9 , 1/3)
x[sapply(x, function(y) min(abs(c(y%%1, y%%1-1))) < tol)]
[1] 1 2 3 4 5 6 7 8 9

      

+3


source


This is an example of a counter-suggestion for using modulo operators:

> x <-  seq(1/3, 9 , 1/3)
> x[!x%%1]
[1] 1 3 4 9
> x
 [1] 0.3333333 0.6666667 1.0000000 1.3333333 1.6666667 2.0000000
 [7] 2.3333333 2.6666667 3.0000000 3.3333333 3.6666667 4.0000000
[13] 4.3333333 4.6666667 5.0000000 5.3333333 5.6666667 6.0000000
[19] 6.3333333 6.6666667 7.0000000 7.3333333 7.6666667 8.0000000
[25] 8.3333333 8.6666667 9.0000000

      



There are many examples of similar questions on SO about why not make this assumption that integers will reliably follow from typical operations on numeric values. Canonical Warning - R-FAQ 7.31. On my device, this is in the R: help page 7.31 Why doesn't R think these numbers are equal?

. More robust approach:

> x[ abs(x-round(x) ) < 0.00000001 ]
[1] 1 2 3 4 5 6 7 8 9

      

+7


source







All Articles