Я предлагаю альтернативный путь для создания последовательностей индексации: seq_len
, который реагирует интуитивно в крайних случаях.
Нижняя линия переднего фронта : используйте sum(X[-seq_len(i)]) - sum(X[seq_len(i-1)])
вместо.
Во-первых, некоторые примеры данных:
X <- 1:10
N <- length(X)
Ваш подход на двух крайностях:
i <- 1
X[(i+1):N]
# [1] 2 3 4 5 6 7 8 9 10
X[1:(i-1)] # oops
# [1] 1
То, что должно возвращать "ничего", я считаю. (Более того, sum(...)
должно возвращать 0. Для записи sum(integer(0))
равно 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
Есть другая ошибка, в которой вы ожидаете "ничего" в первом подмножестве.
Вместо этого я предлагаю вам использовать 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
Оба кажутся хорошими, и что-то посередине имеет смысл.
i <- 5
X[-seq_len(i)]
# [1] 6 7 8 9 10
X[seq_len(i-1)]
# [1] 1 2 3 4
В этом надуманном примере мы ищем любое значение 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
И теперь мы получаем это:
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
Редактировать
ответ заставил меня подумать, что вам не нужно повторно sum
числа до и после всего времени. Просто сделайте это один раз и используйте его снова. Этот метод может быть немного быстрее, если ваш вектор большой.
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
Итак, это говорит о том, что ваше суммарное значение при любом значении i
равно
Xs <- Xa - Xb
Xs
# [1] 54 51 46 39 30 19 6 -9 -26 -45
, где вы можете найти конкретное значение с помощью Xs[i]
. Повторное суммирование не требуется.