Identify repetitive pattern in numeric vector in R with fuzzy search [duplicate] - r

This question already has answers here:
Find and break on repeated runs
(3 answers)
Closed 6 years ago.
Imagine a vector of integers like so:
> rep(c(1,4,2),10)
[1] 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2
For us human beings it seems easy to identify the pattern 1 - 4 - 2 even without knowing the function how the vector was created. But how would you identify this pattern using R?
Edit
As this question was marked as a dupe I'm going to specify it a bit. The above example was an easy one to explain the idea. The main goal would be to identify more hidden patterns like 1 4 2 5 6 7 1 4 2 9 1 4 2 3 4 5 1 4 2 and also patterns that are approximately the same like 1 4 2 1 4 1.99 1 4 2 1.01 4 2 1 4.01 2. What are the ideas to always Identify the pattern 1 4 2 in those cases?

Assuming that the subpattern must start at the beginning and repeat to the end of the input try it for a subpattern length of k = 1, 2, 3, ... We have assumed that only patterns that are half the length of the input or less are to be considered:
for(k in seq_len(length(x)/2)) {
pat <- x[1:k]
if (identical(rep(pat, length = length(x)), x)) {
print(pat)
break
}
}
## [1] 1 4 2
Note: This was used as the input x:
x <- rep(c(1, 4, 2), 10)

Related

How can I remove one number each time while replicating a number of sequence in r? [duplicate]

This question already has answers here:
Generate an incrementally increasing sequence like 112123123412345
(4 answers)
Closed 1 year ago.
I have a sequence of numbers like this:
> seq(2,6,1)
[1] 2 3 4 5 6
I would like to replicate this sequence and remove one number from the end of the sequence while doing replication. This is what I want to have:
[1] 2 3 4 5 6 2 3 4 5 2 3 4 2 3 2
Is there any functions in R can help me get this sequence?
Thank you very much.
I am sure there is a fancier way, but the following code achieves the goal in base R.
out = integer()
a = 2:6
while( length(a) > 1 ) {
a = a[-length(a)]
out = c(out, a)
}
out
#> [1] 2 3 4 5 2 3 4 2 3 2
Created on 2021-03-18 by the reprex package (v1.0.0)
That should be it:
sequence(5:1, from = 2)
[1] 2 3 4 5 6 2 3 4 5 2 3 4 2 3 2

runner:streak_run shows unexpected result when k remains unchanged

I'm using runner:streak_run to count sequences of 0 and 1 in a column called "inactive_indicator".
The column is= 0,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1
For runner::streak_run(inactive_indicator))
I get the following:
1,2,3,1,2,3,1,1,2,1,2,3,4,5,5,5,5,1,2,3,4
Why is it stuck on 5 when it should go up to 8?
In documentation it says that k - running window size. By default window size equals length(x). Allow varying window size specified by vector of length(x)
As I understand, the default definition should be enough.
Problem resolves and I get expected results when running:
runner::streak_run(inactive_indicator),k=length(inactive_indicator))
Why doesn't it work in the first place?
This can be solved with rle from base R
sequence(rle(inactive_indicator)$lengths)
#[1] 1 2 3 1 2 3 1 1 2 1 2 3 4 5 6 7 8 1 2 3 4
Checked with runner
runner::streak_run(inactive_indicator)
#[1] 1 2 3 1 2 3 1 1 2 1 2 3 4 5 6 7 8 1 2 3 4
It is possible that there are some leading/lagging spaces in the column and it is not numeric. In that case, use trimws
runner::streak_run(trimws(inactive_indicator))
data
inactive_indicator <- c(0,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1)

I am trying to take a vector of numbers 5:0 and repeat it 3 times, every other time reversing its order

I'd think this would be simple using the rev() and seq() functions, but am struggling to get the reverse order part correct.
I'm trying to get 5432101234543210 from 5:0.
Not too hard to set as a function...
try_it <- function(x) {
c(rev(x), x[2:length(x-1)], rev(x)[2:length(x-1)])
}
try_it(0:5)
# [1] 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0
Edit
Extend function to have variable repeats
try_it <- function(x, reps) {
c(rev(x), rep(c(x[2:length(x-1)], rev(x)[2:length(x-1)]), (reps - 1) / 2))
}
try_it(0:5, 5)
# [1] 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0
Note: I've not worked hard to generalise this extension, it will not return the correct length for an even number of repetitions. I'm sure you could modify to suit your requirements.

Creating a repeating vector sequence in R [duplicate]

This question already has an answer here:
Generate a repeating sequence based on vector
(1 answer)
Closed 5 years ago.
I need some help. How to create the following vector sequence:
1 1 1 1 2 2 2 3 3 4
I tried to use (rep) and (seq) but still unsucessfull.
Try this:
rep(1:4,4:1)
Output:
[1] 1 1 1 1 2 2 2 3 3 4
or less concisely: c(rep(1, 4), rep(2,3), rep(3, 2), 4)
output: [1] 1 1 1 1 2 2 2 3 3 4

Finding all combinations of four numbers that equal a sum in R [duplicate]

This question already has an answer here:
Find all combinations of numbers that sum to a target
(1 answer)
Closed 7 years ago.
Is there a more efficient way to determine all possible values of 4 numbers that sum a particular value. I have used the following but if I expand it more then ten numbers per group or more then 4 groups it will be inefficient
Grid <- expand.grid(a=seq(0, 100, 10), b= seq(0,100,10), c= seq(0,100,10), d=seq(0,100,10))
Grid$total <- apply(Grid, 1, sum)
Grid[Grid$total==100,]
I my real application, the number will be percentages that will equal to 1 and will be adjusted by intervals of no less then 5
I'm sure there are many solutions, here is one with partitions library,
library(partitions)
restrictedparts(10, 4, include.zero = FALSE)
# [1,] 7 6 5 4 5 4 3 4 3
# [2,] 1 2 3 4 2 3 3 2 3
# [3,] 1 1 1 1 2 2 3 2 2
# [4,] 1 1 1 1 1 1 1 2 2
This would be the 4 integers that sum to 10 (not including 0).

Resources