Создание (наполовину) регулярной последовательности - регулярная норма переменных интервалов

Я хочу создать своего рода вложенную регулярную последовательность в R. Она повторяет шаблон, но без постоянных интервалов между значениями. Это:

8, 9, 10, 11, 12, 13, 17, 18, 19, 20, 21, 22, 26, 27, 28, ....

Итак, 6 чисел с интервалом 1, затем с интервалом 3, а затем снова то же самое. Я бы хотел, чтобы это было примерно до 200, в идеале - возможность указать конечную точку.

Я пытался использовать rep а также seq, но не знаю, как получить регулярно изменяющуюся длину интервала в любую функцию.

Я начал строить ее и думать о создании функции шага, основанной на длине... это не может быть так сложно - что за пакет трюков / магии я не знаю??

3 ответа

Решение

Не делая никакой математики, чтобы выяснить, сколько групп и тому подобное, мы можем просто чрезмерно генерировать.

Определяя терминологию, я скажу, что у вас есть несколько групп последовательностей, по 6 элементов на группу. Мы начнем с 100 групп, чтобы убедиться, что мы определенно пересекаем 200 пороговых значений.

n_per_group = 6
n_groups = 100

# first generate a regular sequence, with no adjustments
x = seq(from = 8, length.out = n_per_group * n_groups)

# then calculate an adjustment to add 
# as you say, the interval is 3 (well, 3 more than the usual 1)
adjustment = rep(0:(n_groups - 1), each = n_per_group) * 3

# if your prefer modular arithmetic, this is equivalent
# adjustment = (seq_along(x) %/% 6) * 3

# then we just add
x = x + adjustment

# and subset down to the desired result
x = x[x <= 200]

x
#  [1]   8   9  10  11  12  13  17  18  19  20  21  22  26  27  28  29  30
# [18]  31  35  36  37  38  39  40  44  45  46  47  48  49  53  54  55  56
# [35]  57  58  62  63  64  65  66  67  71  72  73  74  75  76  80  81  82
# [52]  83  84  85  89  90  91  92  93  94  98  99 100 101 102 103 107 108
# [69] 109 110 111 112 116 117 118 119 120 121 125 126 127 128 129 130 134
# [86] 135 136 137 138 139 143 144 145 146 147 148 152 153 154 155 156 157
#[103] 161 162 163 164 165 166 170 171 172 173 174 175 179 180 181 182 183
#[120] 184 188 189 190 191 192 193 197 198 199 200

Различия между последовательными значениями в последовательности определяются diffs так что возьмите cumsum из тех. Чтобы получить примерно 200, используйте указанное значение повторения, где 1+1+1+1+1+4 = 9.

diffs <- c(8, rep(c(1, 1, 1, 1, 1, 4), (200-8)/9))
cumsum(diffs)

давая:

 [1]   8   9  10  11  12  13  17  18  19  20  21  22  26  27  28  29  30  31
 [19]  35  36  37  38  39  40  44  45  46  47  48  49  53  54  55  56  57  58
 [37]  62  63  64  65  66  67  71  72  73  74  75  76  80  81  82  83  84  85
 [55]  89  90  91  92  93  94  98  99 100 101 102 103 107 108 109 110 111 112
 [73] 116 117 118 119 120 121 125 126 127 128 129 130 134 135 136 137 138 139
 [91] 143 144 145 146 147 148 152 153 154 155 156 157 161 162 163 164 165 166
[109] 170 171 172 173 174 175 179 180 181 182 183 184 188 189 190 191 192 193
[127] 197

Моей первой попыткой было бы использование циклов for, но имейте в виду, что они медленнее по сравнению со встроенными функциями. Но так как вы хотите только "сосчитать" до 200, это должно быть достаточно быстро.

for(i=1:199) {
    if( mod(i, 7) != 0) {
        result[i+1] = result[i] + 1;
    } else {
        result[i+1] = result[i] + 3;
    }
}

примечание: у меня нет Matlab на моем компьютере во время ответа, поэтому приведенный выше код не проверен, но я надеюсь, что вы поняли идею.

Другие вопросы по тегам