This question already has an answer here:
Order of operator precedence when using ":" (the colon)
(1 answer)
Closed 4 years ago.
I have a vector and would like to extract element 3 and 4. Can you please help me understand what the logic is behind the code version without parenthesis? I appreciate your help.
a=c(1:5)
a[(2+1): 4] # with parenthesis, makes sense
[1] 3 4
a[ 2+1 : 4] # without parenthesis, what is the logic here?
[1] 3 4 5 NA
The : operator is evaluated before the + operator.
Consider
print(c(2+1:4))
This returns
[1] 3 4 5 6
Because a vector 1,2,3,4 is created, then all elements are added by 2.
R Operator Syntax and Precedence
gives an overview over the priority of R's operators. The sequence operator : comes before the arithmetic operators like + or -.
Related
This question already has an answer here:
Order of operator precedence when using ":" (the colon)
(1 answer)
Closed 5 months ago.
I am a beginner in R. I was wondering why 1:n-1 1:(n-1) would come out different output?
n = 4
1:n-1
[1]0 1 2 3
n = 4
1:(n-1)
[1]1 2 3
Thanks a lot.
It is related to the precedence of operators in R (see https://stat.ethz.ch/R-manual/R-devel/library/base/html/Syntax.html)
As we can see, : has higher precedence than +- (add, substract), that means
1:n-1 is actually (1:n)-1, which is definitely different from 1:(n-1)
You need to put n-1 into brackets if you want it to be evaluated first, as : is binding stronger than -. 1:n-1 evaluates 1:n first and then subtracts 1 from each element.
In your example, 1:n yields
[1] 1 2 3 4
```
Subtraction by 1 yields:
```
[1] 0 1 2 3
```
This question already has an answer here:
Operator precedence of "unary minus" (-) and exponentiation (^) outside vs. inside function
(1 answer)
Closed 8 months ago.
R seems pretty comfortable with computing the odd root of a negative number
-0.2^(1/3) # returns a good number
# [1] -0.5848035
but something weird happens if you raise a vector to the 1/3.
c(-0.2, 1)^(1/3) # returns an NA for the first element
# [1] NaN 1
I'm interested in an answer that explains what is happening differently to the vector than to the negative value when provided as a numeric scalar.
I'm not looking for a workaround e.g. function(x){sign(x)*(abs(x))^(1/3)}. This answer seems to point in a good direction... how does the "^" operator think differently about vectors and scalars?
I'm not looking for a workaround e.g. function(x) {sign(x) * (abs(x)) ^ (1/3)}.
I'm interested in an answer that explains what is happening differently to the vector than to the negative value when provided as a numeric scalar.
how does the ^ operator think differently about vectors and scalars?
You seem to believe that c(-0.2, 1)^(1/3) translates to c(-0.2^(1/3), 1^(1/3)). This is incorrect. Operator ^ is actually a function, that is, (a) ^ (b) is as same as "^"(a, b). Therefore, the correct interpretation goes as follows:
c(-0.2, 1)^(1/3)
=> "^"(c(-0.2, 1), 1/3)
=> c( "^"(-0.2, 1/3), "^"(1, 1/3) )
=> c( (-0.2)^(1/3), (1)^(1/3) )
=> c( NaN, 1 )
Now, why doesn't -0.2^(1/3) give NaN? Because ^ has higher operation precedence than +, -, * and /. So as it is written, it really implies -(0.2^(1/3)) instead of (-0.2)^(1/3).
The lesson is that, to avoid buggy code, write your code as (a) ^ (b) instead of just a ^ b.
Additional Remark:
I often compare ^ and : when teaching R to my students, because they have different behaviors. But they all show the importance of protecting operands with brackets.
(-1):2
#[1] -1 0 1 2
-1:2
#[1] -1 0 1 2
-(1:2)
#[1] -1 -2
2*3:10
#[1] 6 8 10 12 14 16 18 20
(2*3):10
#[1] 6 7 8 9 10
2*(3:10)
#[1] 6 8 10 12 14 16 18 20
See ?Syntax for details of operator precedence.
This question already has answers here:
Is there an R function for finding the index of an element in a vector?
(4 answers)
Closed 4 years ago.
I am confused about the which function. Basically I thought that it checks at which position of an input object (e.g., a vector) a logical condition is true. As seen in the documentation:
which(LETTERS == "R")
[1] 18
In other words, it goes through all LETTERS values and checks if value == R. But this seems to be a misunderstanding. If I input
a <- c("test","test2","test3","test4")
b <- c("test","test3")
which(a==b)
[1] 1
it returns [1] 1 although test3 does also appear in both vectors. Also, if I input a shorter vector for a, it returns a warning:
a <- c("test","test2","test3")
b <- c("test","test3")
which(a==b)
[1] 1
Warning message:
In a == b : longer object length is not a multiple of shorter object length
My question here is twofold:
How can I return the positions of a character vector a that match a character vector b?
How does which() operate because I obviously misunderstand the function.
Thank you for your answers
Edit: thank you for your quick replies, you clarified my misunderstanding!
You need to give which an input that tells it what elements of a are in b:
which(a%in%b)
[1] 1 3
which essentially identifies which elements are TRUE in a logical vector.
== compares values 1 by 1 (a[1]==b[1]);(a[2]==b[2])..... and not as sets.
for set operations use %in%
use a[which(a %in% b)] to get [1] "test" "test3"
which() returns the index of TRUE expressions (!) not the value.
which(a %in% b) will return
[1] 1 3
the reason for the strange warning message is R's recycling
Warning message:
In a == b : longer object length is not a multiple of shorter object length
so when you compare a vector of length 4 with a vector of length 2, value by value (using == ), R 'recycles' the short vector. in 4 and 2 it works and you will get an answer for this question: (a1==b1,a2==b2,a3==b1,a4==b2). in case of length 4 and 3 - you get a warning message saying the short vector cannot be multiplied by an integer to get the long vector length.
This question already has an answer here:
Why does the vector gets expanded in the loop
(1 answer)
Closed 6 years ago.
I am running into some behaviour with R that I find confusing. Does anyone have any insight into what is going on here?
Define two objects
i <- 5
nr <- 10
So i + 2 and nr + 1
> i+2
[1] 7
> nr+1
[1] 11
So to create a sequence from 7 to 11 I could do this:
7:11
But my question why does this not produce the same result?
i+2:nr+1
We already established above that it's input numbers are equivalent. Obviously I'm missing something here but I just don't know what it is.
You have just discovered the prime R gotcha, namely: 1:n-1 produces the sequence 0, 1, 2, ..., n-1.
To obtain what you desire, wrap the expressions in brackets:
1:(n-1)
or use
seq.int(1, n-1)
The reason for the issue is operator precedence - ?Syntax`
I'm currently attempting to work out the GCD of two numbers (x and y) in R. I'm not allowed to use loops or if, else, ifelse statements. So i'm restricted to logical and arithmetic operators. So far using the code below i've managed to make lists of the factors of x and y.
xfac<-1:x
xfac[x%%fac==0]
This gives me two lists of factors but i'm not sure where to go from here. Is there a way I can combine the common elements in the two lists and then return the greatest value?
Thanks in advance.
Yes, max(intersect(xfac,yfac)) should give the gcd.
You have almost solved the problem. Let's take the example x <- 12 and y <- 18. The GCD is in this case 6.
We can start by creating vectors xf and yf containing the factor decomposition of each number, similar to the code you have shown:
xf <- (1:x)[!(x%%(1:x))]
#> xf
#[1] 1 2 3 4 6 12
yf <- (1:y)[!(y%%(1:y))]
#> yf
#[1] 1 2 3 6 9 18
The parentheses after the negation operator ! are not necessary due to specific rules of operator precedence in R, but I think that they make the code clearer in this case (see fortunes::fortune(138)).
Once we have defined these vectors, we can extract the GCD with
max(xf[xf %in% yf])
#[1] 6
Or, equivalently,
max(yf[yf %in% xf])
#[1] 6