This question already has answers here:
r programming - check for every value in a vector if it is numeric
(2 answers)
Closed 6 years ago.
Suppose I have a vector
x <- c('a', 'b', 1, 2)
What is the easiest way for me to get an output that indicates whether or not the components of x are numeric? I.e., the output should be
something(x)
[1] FALSE FALSE TRUE TRUE
The way I know how to do this is to convert x to a matrix and use apply:
apply(as.matrix(x), FUN = is.numeric, MARGIN = 1)
But after testing, this actually doesn't work - I forgot that the types are coerced to become strings.
We can use is.na and as.numeric
!is.na(as.numeric(x))
#[1] FALSE FALSE TRUE TRUE
with a friendly warning
Or use grep to match only numeric elements from start (^) to end ($)
grepl("^-?[0-9.]+$", x)
#[1] FALSE FALSE TRUE TRUE
Related
This question already has answers here:
Why TRUE == "TRUE" is TRUE in R?
(3 answers)
Why does "one" < 2 equal FALSE in R?
(2 answers)
Closed last year.
It appears that as.character() of a number is still a number, which I find counter intuitive. Consider this example:
1 > "2"
[1] FALSE
2 > "1"
[1] TRUE
Even if I try to use as.character() or paste()
as.character(2)
[1] "2"
as.character(2) > 1
[1] TRUE
as.character(2) < 1
[1] FALSE
Why is that? Can't I have R return an error when I am comparing numbers with strings?
As explained in the comments the problem is that the numeric 1 is coerced to character.
The operation < still works for characters. A character is smaller than another if it comes first in alphabetical order.
> "a" < "b"
[1] TRUE
> "z" < "b"
[1] FALSE
So in your case as.character(2) > 1 is transformed to as.character(2) > as.character(1) and because of the "alphabetical" order of numbers TRUEis returned.
To prevent this you would have to check for the class of an object manually.
The documentation of ?Comparison states that
If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.
So in your case the number is automatically coerced to string and the comparison is made based on the respective collation.
In order to prevent it, the only option I know of is to manually compare the class first.
This question already has answers here:
Why does "one" < 2 equal FALSE in R?
(2 answers)
Why is the expression "1"==1 evaluating to TRUE? [duplicate]
(1 answer)
Closed 3 years ago.
Just like the title says, why does "1" == 1 is TRUE? What is the real reason behind this? Is R trying to be kind or is this something else? I was thinking since "1" (or any numbers it really doesn't matter) where read by R as a character it would automatically return FALSE if compare with as.numeric(1) or as.integer(1).
> as.character(1) == as.numeric(1)
[1] TRUE
or
> "1" == 1
[1] TRUE
I guess it is a simple question but I'd like to get an answer. Thank you.
According to ?==
For numerical and complex values, remember == and != do not allow for the finite representation of fractions, nor for rounding error. Using all.equal with identical is almost always preferable. S
In another paragraph, it is also written
x, y
atomic vectors, symbols, calls, or other objects for which methods have been written. If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.
identical(as.character(1), as.numeric(1))
#[1] FALSE
This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 5 years ago.
I have a 1 column matrix with labels and a numeric vector.
I want to extract the labels in the matrix which are equal to one of the entries in that vector, more specifically:
> mat
[,1]
intercept 20.86636535
crim -0.23802478
zn 0.03822050
indus 0.05135584
chas 2.43504780
> vec
[1] -0.23802478 0.05135584
> mat[2, 1] == vec[1]
crim
FALSE
Currently I'm stuck with the first step. I have no idea why it returns FALSE while they hold the same numeric values.
I'd use round(as.numeric(mat[,2, drop=T]), 5) %in% round(vec, 5)
, as there may well be floating point issues.
Doing so yields:
[1] FALSE TRUE FALSE TRUE FALSE
Basically, you need to turn the second column into a vector (using drop=T) and then turn it from a character to a numeric. The rounding (in this case, to 5 decimal places) then bridges the floating point problem that I mentioned before (along with David Arenburg).
I hope that helps you.
This question already has answers here:
How to delete multiple values from a vector?
(9 answers)
Closed 5 years ago.
I have a vector called data which has approximately 35000 elements (numeric). And I have a numeric vector A. I want to remove every appearance of elements of A in the vector data. For example if A is the vector [1,2]. I want to remove all appearance of 1 and 2 in the vector data. How can I do that? Is there a built in function that does this? I couldn't think of a way. Doing it with a loop would take a long time I assume. Thanks!
There is this handy %in%-operator. Look it up, one of the best things I can think of in any programming language! You can use it to check all elements of one vector A versus all elements of another vector B and returns a logical vector that gives the positions of all elements in A that can be found in B. It is what you need! If you are new to R, it might seem a bit weird, but you will get very much used to it.
Ok, so how to use it? Lets say datvec is your numeric vector:
datvec = c(1, 4, 1, 7, 5, 2, 8, 2, 10, -1, 0, 2)
elements_2_remove = c(1, 2)
datvec %in% elements_2_remove
## [1] TRUE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE
So, you see a vector that gives you the positions of either 1 or 2 in datvec. So, you can use it to index what yuo want to retain (by negating it):
datvec = datvec[!(datvec %in% elements_2_remove)]
And you are done!
This question already has answers here:
Test if a vector contains a given element
(8 answers)
Closed 9 years ago.
Say I have a numerical vector in R. And I want to see if a particular integer is present in the vector or not. We can do that easily in python using 'in' command and an if statement may be.
Do we have something similar in R as well? So that I don't have to use a for loop to check if the integer I want is present in a vector? I tried the following, but it does not seem to work. 'normal' is a dataframe and the second column has integers.
if (12069692 in normal[,2]) {print("yes")}
Says,
Error: unexpected 'in' in "if (12069692 in"
In R, it's called %in%:
> 1 %in% c(1, 2, 3)
[1] TRUE
> 4 %in% c(1, 2, 3)
[1] FALSE
It is vectorized on the left-hand side, so you can check multiple values at once:
> c(1, 4, 2, 1) %in% c(1, 2, 3)
[1] TRUE FALSE TRUE TRUE
(hat tip #Spacedman)