How many times does the sign change in my vector? [duplicate] - r

This question already has answers here:
Counting the number of times a value change signs with R
(2 answers)
Closed 1 year ago.
I would like you to help me to create a function that helps me to identify how many times does the sign of the numbers in a vector change, for example:
1,2,-5,-6,-7,5,1,-8
How could my function identify that there are 3 sign changes?

Try the code below
> sum(diff(sign(v))!=0)
[1] 3
or
> sum(rowSums(embed(sign(v), 2)) == 0)
[1] 3
Data
v <- c(1, 2, -5, -6, -7, 5, 1, -8)

Using rle :
x <- c(1, 2, -5, -6, -7, 5, 1, -8)
length(rle(sign(x))$lengths) - 1
#[1] 3

Related

How to get the positions of the k greatest(or smallest) elements of a vector? [duplicate]

This question already has answers here:
How to find the largest N elements in a list in R?
(4 answers)
Closed 10 months ago.
I have a vector and I want to find the indices of the k greatest elements, not the elements themselves which I could do with sort. One idea would be to add indices to the values and have a custom sort function that only compares the first elements of pairs (a classical solution to this problem) but surely there has to be a simpler way ? Note that performance isn`t a matter.
First I create a random vector:
vector <- c(1, 3, 6, 2, 7, 8, 10, 4)
Next, you can use the following code which will output the top k elements as x with index ix:
k <- 3
lst <- sort(vector, index.return=TRUE, decreasing=TRUE)
lapply(lst, `[`, lst$x %in% head(unique(lst$x),k))
Output:
$x
[1] 10 8 7
$ix
[1] 7 6 5
As you can see ix gives the index of the top k elements.
Using rank.
x <- c(1, 3, 6, 2, 7, 8, 10, 4)
seq_along(x)[rank(-x) < 4]
# [1] 5 6 7
If you have ties, the result is this:
x <- c(10, 3, 6, 2, 7, 8, 10, 4)
seq_along(x)[rank(-x) < 4]
# [1] 1 6 7

Function that reveals the position in R [duplicate]

This question already has answers here:
rank and order in R
(7 answers)
Closed 4 years ago.
What is the difference between sort(), rank(), and order() in R.
Can you explain with examples?
sort() sorts the vector in an ascending order.
rank() gives the respective rank of the numbers present in the vector, the smallest number receiving the rank 1.
order() returns the indices of the vector in a sorted order.
for example: if we apply these functions are applied to the vector - c (3, 1, 2, 5, 4)
sort(c (3, 1, 2, 5, 4)) will give c(1,2,3,4,5)
rank(c (3, 1, 2, 5, 4)) will give c(3,1,2,5,4)
order(c (3, 1, 2, 5, 4)) will give c(2,3,1,5,4).
if you put these indices in this order, you will get the sorted vector. Notice how v[2] = 1, v[3] = 2, v[1] = 3, v[5] = 4 and v[4] = 5
also there is a tie handling method in R. If you run rank(c (3, 1, 2, 5, 4, 2)) it will give Rank 1 to 1, since there are two 2 present R will rank them on 2 and 3 but assign Rank 2.5 to each of them, next 3 will get Rank 4.0, so
rank(c (3, 1, 2, 5, 4, 2)) will give you output [4.0 1.0 2.5 6.0 5.0 2.5]
Hope this is helpful.

How return the count of number of occurrences of an integer in a vector, in a new vector using R [duplicate]

This question already has answers here:
Count the occurrence of one vector's values in another vector
(2 answers)
Comparing Vectors Values: 1 element with all other
(2 answers)
Closed 4 years ago.
New to R. I have seen a lot of similar questions where tables are used to count the number of occurrences, but I want to create a new vector for each integer in vector_1 (e.g. 1 through 10,), where the number of occurrences of the integer in vector_1 is checked in vector_2, and then returned in a third vector_3.
Desired Result:
vector_1 <- c(1:10)
vector_2 <- c(3, 4, 4, 5, 7, 9, 10)
vector_3 <- c(0, 0, 1, 2, 1, 0, 1, 0, 1, 1)
I have tried using for loops such as:
for (i in 1:10) {
for (j in vector_2) {
print(i) <- vector_3
}
}
Obviously this code doesn't work, but I am just not finding a good way to do a summation of the occurrences between the vectors. Any guidance or alternate approaches would be welcomed.
*Edit: most all answers that I have seen to similar questions use tables to count the occurrences within vector_2; I haven't come across questions that compare the two vectors and then output the result.
Your code doesn't make sense to me. Anyway, you can easily compare each value in vector 1 with each value in vector 2 using outer. rowSums then can give you the required counts.
vector_1 <- c(1:10)
vector_2 <- c(3, 4, 4, 5, 7, 9, 10)
rowSums(outer(vector_1, vector_2, "=="))
#[1] 0 0 1 2 1 0 1 0 1 1
Also you can create a factor variable:
vector_2 <- c(3, 4, 4, 5, 7, 9, 10)
vector_2 <- factor(vector_2,levels = 1:10)
table(vector_2)

Remove continuously repeating values [duplicate]

This question already has answers here:
Remove/collapse consecutive duplicate values in sequence
(5 answers)
Closed 4 years ago.
Does anyone know how to remove continuously repeating values? Not just repeating values with unique() function.
So for example, I want:
0,0,0,0,1,1,1,2,2,2,3,3,3,3,2,2,1,2
to become
0,1,2,3,2,1,2
and not just
0,1,2,3
Is there a word to describe this? I'm sure that the solution is out there somewhere and I just can't find it because I don't know the word for it.
Keep a value when it's difference from the previous value is not zero (and keep the first one):
x <- c(0,0,0,0,1,1,1,2,2,2,3,3,3,3,2,2,1,2)
x[c(1, diff(x)) != 0]
# [1] 0 1 2 3 2 1 2
v <- c(0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 2, 2, 1, 2)
rle(v)$values
Output:
[1] 0 1 2 3 2 1 2

Finding groups of contiguous numbers in a list [duplicate]

This question already has answers here:
Sequence length encoding using R
(6 answers)
Closed 9 years ago.
This is a duplicate question to this, except for R rather than Python.
I'd like to identify groups of contiguous (some people call them continuous) integers in a list, where duplicate entries are treated as existing within the same range. Therefore:
myfunc(c(2, 3, 4, 4, 5, 12, 13, 14, 15, 16, 17, 17, 20))
returns:
min max
2 5
12 17
20 20
Although any output format would be fine. My current brute-force, for-loop method is pretty slow.
(Apologies if I could have easily re-interpreted the Python answer and I'm being stupid!)
Just use diff:
x = c(2, 3, 4, 4, 5, 12, 13, 14, 15, 16, 17, 17, 20)
start = c(1, which(diff(x) != 1 & diff(x) != 0) + 1)
end = c(start - 1, length(x))
x[start]
# 2 12 20
x[end]
# 5 17 20

Resources