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

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

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

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

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

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


person n1k31t4    schedule 08.12.2015    source источник


Ответы (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
person Gregor Thomas    schedule 08.12.2015
comment
Это здорово - просто и масштабируемо для дальнейшего использования. Это был этап adjustment, на котором мое программирование не оправдалось — я знал, что это то, что я хотел сделать, но не знал, как войти в код. Большое спасибо! - person n1k31t4; 09.12.2015
comment
Мне также нужно было добавить na.trim, так как перегенерированные значения остались как значения NA. Итак, последний шаг: x = na.trim(x[x ‹= 200]) - person n1k31t4; 09.12.2015
comment
Я не уверен, что вы сделали, чтобы представить NAs, но все, что работает для вас. (Вы можете увидеть мой вывод, скопированный после запуска моего точного кода - без na.trim, без NAs.) - person Gregor Thomas; 09.12.2015

Различия между последовательными значениями в последовательности равны 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
person G. Grothendieck    schedule 08.12.2015
comment
Заменили фиксированное количество повторений расчетом, который позволит получить серию примерно до 200. - person G. Grothendieck; 09.12.2015

Моя первая попытка будет использовать циклы 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, поэтому приведенный выше код не тестировался, но я надеюсь, что вы поняли идею.

person Florian Z.    schedule 08.12.2015
comment
Это было мое последнее средство, которое вы успели опубликовать до того, как я туда попал! Спасибо - person n1k31t4; 09.12.2015