R диапазоны: 1: 0 - нелогичное поведение - PullRequest
0 голосов
/ 30 августа 2018

У меня есть массив X длины N, и я бы хотел вычислить sum(X[(i+1):N]) - sum(X[1:(i-1)]. Это прекрасно работает, если мой индекс i находится в пределах 2 .. (N-1). Если он равен 1, второе слагаемое вернет первый элемент массива, а не исключит его. Если он равен N, первый член вернет последний элемент массива, а не исключит его. seq_len - единственная функция, о которой я знаю, которая выполняет свою работу, но только для 2-го члена (индекс 1: n). Что мне нужно, так это функция диапазона, которая будет возвращать NULL (а не генерировать исключение, подобное seq), когда ее второй аргумент будет ниже первого. Функция sum сделает все остальное. Кто-нибудь знает об этом или я сам должен написать?

1 Ответ

0 голосов
/ 31 августа 2018

Я предлагаю альтернативный путь для создания последовательностей индексации: 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]. Повторное суммирование не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...