Test.Vect = runif(101)
n = 90
count.n = 101
Test.Vect[n+1:count.n]
all(Test.Vect[91:101] == Test.Vect[(n+1):count.n])
all(Test.Vect[n+1:count.n] == Test.Vect[(n+1):count.n])
Why does line 4 and 5 not match i.e. line 6 fail?
Line 6,
all(Test.Vect[n + 1:count.n] == Test.Vect[(n + 1):count.n])
fails because of operator precedence. The : expression is evaluated and then the + expression is evaluated.
Take the following example,
1 + 1:5
# [1] 2 3 4 5 6
(1 + 1):5
# [1] 2 3 4 5
Thus, on line 6 instead of extracting elements 91 through 101 you are extracting elements 90 + (1 through 101) or 91 through 191. Check out the ?Syntax help page for further information on operator precedence.
Related
So I have a dataframe and I want to create a new variable randomly using other factors; my data contains this key variables:
iQ
Age
Educ_y
5
23
15
4
54
17
2
43
6
3
13
7
5
14
8
1
51
16
I want to generate a new variable (years of experience) randomly using this creterias:
If Age >= 15 & Iq<= 2 so "Exp_y" takes a randome number between (Age-15)/2 and Age-15.
If (Age >= 15 & (Iq==3 | Iq==4) so "Exp_y" takes a randome number between (Age-Educ_y-6)/2 and (Age-Educ_y-6).
And 0 otherwise.
I tried using this code :
Df <- Df %>%
rowwise() %>%
mutate(Exep_y = case_when(
Age > 14 & iq <= 2 ~ sample(seq((Age-15)/2, Age-15, 1), 1),
Age > 14 & between(iq, 3, 4) ~ sample(seq((Age-Educ_y-6)/2, Age-Educ_y-6, 1), 1),
TRUE ~ 0
))
But I end up with this Error message:
Error in `mutate()`:
! Problem while computing `Exep_y = case_when(...)`.
i The error occurred in row 3.
Caused by error in `seq.default()`:
! signe incorrect de l'argument 'by'
Any ideas please;
Best Regards
This error message is occurring because the case_when() statement evaluates all the right-hand-side expressions, and then selects based on the left-hand-side.. Therefore, even though, for example row 4 of your sample dataset will default to TRUE~0, the RHS side of the the first two conditions also gets evaluated. In this case, the first condition's RHS is seq((13-15)/2,13-15,1), which returns an error, because in this case from = -1 and to = -2, so the by argument cannot be 1 (it is the wrong sign).
seq((13-15)/2, 13-15, 1)
Error in seq.default((13 - 15)/2, 13 - 15, 1) :
wrong sign in 'by' argument
You could do something like this:
f <- function(i,a,e) {
if(i>4 | a<15) return(0)
if(i<=2) return(sample(seq((a-15)/2, a-15),1))
return(sample(seq((a-e-6)/2, a-e-6),1))
}
Df %>% rowwise() %>% mutate(Exep_y=f(iq,Age,Educ_y))
Output:
iq Age Educ_y Exep_y
<int> <int> <int> <dbl>
1 5 23 15 0
2 4 54 17 16.5
3 2 43 6 21
4 3 13 7 0
5 5 14 8 0
6 1 51 16 27
You could try using if_else() rather than case_when:
Documentation can be found here: https://dplyr.tidyverse.org/reference/if_else.html
(Rstudio) suppose I have a data set of:
# Circle X Y
1 A 21 8
2 A 32 17
3 A 23 32
4 B 22 4
5 B 43 12
6 C 12 4
.....
I need to find the instantaneous velocity of each circle at each time frame.
For line 1 is the starting point so the velocity is 0, and the formula I want to achieve for each circle's (X, Y) coordinates is sqrt(((x2-x1)^2 + (y2-y1)^2)/2)) where the x2 and x1 is from the previous line (e.g. line 1 & line 2, Line 2 & line 3). the final result I want to have is as below:
# Circle X Y Instant velocity
1 A 21 8 0
2 A 32 17 sqrt(((32-21)^2 + (17-8)^2)/2))
3 A 23 32 sqrt(((23-32)^2 + (32-17)^2)/2))
4 B 22 4 0
5 B 43 12 sqrt(((43-22)^2 + (12-4)^2)/2))
6 C 12 4 0
.....
Could anyone help me in achieving this on Rstudio???
You have one more ) than ( in your code example, which makes me a bit confused about where the /2 goes, but if you verify my syntax something like this should work:
library(dplyr)
your_data %>%
group_by(Circle) %>%
mutate(
instant_velocity = coalesce(sqrt(((x - lag(x))^2 + (y - lag(y))^2)/2), 0)
)
I have an array X of length N, and I'd like to compute sum(X[(i+1):N]) - sum(X[1:(i-1)]. This works fine if my index, i, is within 2..(N-1). If it's equal to 1, the second term will return the first element of the array rather than exclude it. If it's equal to N, the first term will return the last element of the array rather than exclude it. seq_len is the only function I'm aware of that does the job, but only for the 2nd term (it indexes 1:n). What I need is a range function that will return NULL (rather than throw an exception like seq) when its 2nd argument is below its first. The sum function will do the rest. Is anyone aware of one, or do I have to write one myself?
I suggest an alternate path for generating indexing sequences: seq_len, which reacts intuitively in the extremes.
Bottom Line Up Front: use sum(X[-seq_len(i)]) - sum(X[seq_len(i-1)]) instead.
First, some sample data:
X <- 1:10
N <- length(X)
Your approach, at the two extremes:
i <- 1
X[(i+1):N]
# [1] 2 3 4 5 6 7 8 9 10
X[1:(i-1)] # oops
# [1] 1
That should return "nothing", I believe. (More the point, sum(...) should return 0. For the record, sum(integer(0)) is 0.)
i <- 10
X[(i+1):N] # oops
# [1] NA 10
X[1:(i-1)]
# [1] 1 2 3 4 5 6 7 8 9
There's your other error, where you'd expect "nothing" in the first subset.
Instead, I suggest you use seq_len:
i <- 1
X[-seq_len(i)]
# [1] 2 3 4 5 6 7 8 9 10
X[seq_len(i-1)]
# integer(0)
i <- 10
X[-seq_len(i)]
# integer(0)
X[seq_len(i-1)]
# [1] 1 2 3 4 5 6 7 8 9
Both seem fine, and something in the middle makes sense.
i <- 5
X[-seq_len(i)]
# [1] 6 7 8 9 10
X[seq_len(i-1)]
# [1] 1 2 3 4
In this contrived example, what we're looking for at any value of i:
1: sum(2:10) - 0 = 54 - 0 = 54
2: sum(3:10) - sum(1:1) = 52 - 1 = 51
3: sum(4:10) - sum(1:2) = 49 - 3 = 46
...
10: 0 - sum(1:9) = 0 - 45 = -45
And we now get that:
func <- function(i, x) sum(x[-seq_len(i)]) - sum(x[seq_len(i-1)])
sapply(c(1,2,3,10), func, X)
# [1] 54 51 46 -45
Edit:
李哲源's answer got me to thinking that you don't need to re-sum the numbers before and after all the time. Just do it once and re-use it. This method could be easily a bit faster if your vector is large.
Xb <- c(0, cumsum(X)[-N])
Xb
# [1] 0 1 3 6 10 15 21 28 36 45
Xa <- c(rev(cumsum(rev(X)))[-1], 0)
Xa
# [1] 54 52 49 45 40 34 27 19 10 0
sapply(c(1,2,3,10), function(i) Xa[i] - Xb[i])
# [1] 54 51 46 -45
So this suggests that your summed value at any value of i is
Xs <- Xa - Xb
Xs
# [1] 54 51 46 39 30 19 6 -9 -26 -45
where you can find the specific value with Xs[i]. No repeated summing required.
This question already has answers here:
Brackets make a vector different. How exactly is vector expression evaluated?
(3 answers)
Closed 6 years ago.
I have the below example code. I have a dataframe ts which has 16 rows. when I subset with actual numbers it works fine but when I subset with calculated numbers why is my code behaving weirdly ?
Can anyone please explain me what's wrong in this?
Case1:
> a
[1] 12
> c
[1] 16
> ts$trend[13:16]
[1] 21.36926 21.48654 21.60383 21.72111
> ts$trend[a+1:c]
[1] 21.36926 21.48654 21.60383 21.72111 NA NA NA NA NA NA NA NA
[13] NA NA NA NA
Case 2:
> b
[1] 4
> temp[1: 8]
[1] 1 2 3 4 5 6 7 8
> temp[1: b+b]
[1] 5 6 7 8
R doesn't care about they way you space expressions. Things are evaluated according to a strict precedence scheme. Things in parentheses are done first. So:
> 1: b+b
[1] 5 6 7 8
because addition has lower precedence than ":". The 1:b is evaluated first, and then b is added. So you get:
> (1:b)+b
[1] 5 6 7 8
If you want the alternative, parenthesise things:
> 1:(b+b)
[1] 1 2 3 4 5 6 7 8
I'd suggest you also parenthesise (1+b):b if that is ever what you want - the brackets make no difference but they aid readability for anyone who forgets the precedence rules.
This is a case of operator precedence. It can be avoided by using brackets
temp[1:(b+b)]
#[1] 1 2 3 4 5 6 7 8
If we check the problem in OP's code
1:b
#[1] 1 2 3 4
(1:b) + b
#[1] 5 6 7 8
So, the operator precedence happens here by evaluating 1:b followed by adding the b.
This is well described in ?Syntax
:: ::: access variables in a namespace
$ # component / slot
extraction [ [[ indexing
^ exponentiation (right to left)
- + unary minus and plus
: sequence operator %any% special operators (including %% and %/%)
* / multiply, divide
+ - (binary) add, subtract
< > <= >= == != ordering and comparison
! negation
& && and
| || or
~ as in formulae
-> ->> rightwards assignment
<- <<- assignment (right to left)
= assignment (right to left)
? help (unary and binary)
data
temp <- 1:10
b <- 4
I'm trying to understand the reason for a rule when converting.
I'm sure there must be a simple explanation, but I can't seem to wrap my head around it.
Appreciate any help!
Converting from base10 to any other base is done like this:
number / desiredBase = number + remainder
You do this until number = 0.
But after all of the calculations, you have to take all the remainders upside down. I don't understand why.
For example: base10 number to base2
11 / 2 = 5 + 1
5 / 2 = 2 + 1
2 / 2 = 1 + 0
1 / 2 = 0 + 1
Why is the correct answer: 1011 and not 1101 ?
I know it's a little petty, but it would really help me remember better if I could understand this.
Think of the same in decimal system, even if it doesn't make that much sense to actually do the math in this case :)
1234 / 10 = 123 | 4
123 / 10 = 12 | 3
12 / 10 = 1 | 2
1 / 10 = 0 | 1
Every time you divide, you strip the least significant digit, so the first result, is the least significant result -- digit on the right.
Because 11 =
1 * 2 ^ 3 + 0 * 2 ^ 2 + 1 * 2 ^ 1 + 1 * 2 ^ 0 (1011)
and not
1 * 2 ^ 3 + 1 * 2 ^ 2 + 0 * 2 ^ 1 + 1 * 2 ^ 0 (1101)