Шаг 1: с помощью единого индекса для адресации матрицы
В матричных элементах R, хранится в столбцах порядка в вектор , поэтому A[i, j]
- это то же самое, что и A[(j-1)*nrow(A) + i]
. Рассмотрим пример случайной матрицы 3 на 3:
set.seed(1); A <- round(matrix(runif(9), 3, 3), 2)
> A
[,1] [,2] [,3]
[1,] 0.27 0.91 0.94
[2,] 0.37 0.20 0.66
[3,] 0.57 0.90 0.63
Теперь эта матрица имеет 3 ряда (nrow(A) = 3
). Сравните:
A[2,3] # 0.66
A[(3-1) * 3 + 2] # 0.66
Шаг 2: векторизации
Вы можете обратиться несколько элементов матрицы одновременно. Однако вы можете сделать это только с помощью одного режима индексирования (не слишком точно здесь, см. Примечание @ alexis_laz). Например, если вы хотите извлечь A[1,2]
и A[3,1]
, но если вы делаете:
A[c(1,3), c(2,1)]
# [,1] [,2]
# [1,] 0.91 0.27
# [2,] 0.90 0.57
Вы фактически получаете блок. Теперь, если вы используете единую индексацию, вы получите то, что вам нужно:
A[3 * (c(2,1) - 1) + c(1,3)]
# [1] 0.91 0.57
Шаг 3: получение одного индекса для вашей проблемы
Пусть n <- length(a)
и вы хотите, чтобы решить эти элементы b
:
a[1] a[2]
a[2] a[3]
. .
. .
a[n-1] a[n]
Вы можете использовать единый указатель nrow(b) * (a[2:n] - 1) + a[1:(n-1)]
.
Шаг 4: полное решение
Поскольку у вас есть только один ряд для a
и c
, следует хранить их в качестве векторов, а не матрицы.
a <- c(1,4,3,1)
c <- 4:8
Если вы получили матрицу и не имеют никакого выбора (как в настоящее время они находятся в вашем вопросе), вы можете преобразовать их в векторы по:
a <- as.numeric(a)
c <- as.numeric(c)
Теперь, как обсуждалось, мы имеем индекс для адреса b
матрицы:
n <- length(a)
b_ind <- nrow(b) * (a[2:n] - 1) + a[1:(n-1)]
Вы также адрес a[1]
элемента c
в качестве первого элемента вашего конечного результата, так что нам нужно concatena т.е: c[a[1]]
и b[b_ind]
по:
a <- c(c[a[1]], b[b_ind])
# > a
# [1] 4 16 14 3
Этот подход полностью векторизация, даже лучше, чем *apply
семьи.
замечание alexis_laz в
alexis_laz напоминает мне, что мы можем использовать "матрица-индекс", а также, например, мы можем также рассмотреть матрицу b
через:
b[cbind(a[1:(n-1)],a[2:n])] ## or b[cbind(a[-n], a[-1])]
Тем не менее, я думаю, что использование единого индекса немного быстрее, потому что нам нужно получить доступ к индексной матрице по строке, чтобы обратиться к b
, поэтому мы платим за задержку памяти, чем с помощью векторного индекса.
Благодарим вас за быстрый ответ. Кажется, что b_ind = b [b_ind] ... Я не понимаю логики этого утверждения b_ind <- nrow (b) * (a [-1] - 1) + a [1: (length (a) -1)] Я проработаю его и посмотрю, лучше ли производительность, чем простой цикл, и вернемся к вам завтра. – Imlerith
должен был дать ему еще одну попытку ... Я понял это сейчас (не знал о R-организационных матрицах таким образом что привело к этому своеобразному отношению) было бы также интересно увидеть применение реализации решения, так как я мало понимаю, как они работают в «сложных» проблемах – Imlerith
Я отредактировал и удалил некоторые из текстов, которые не являются частью ответа (: -). Однако вы можете «откат», если вы считаете это необходимым. (Плюс один - по сути, вы набрали 8 очков). Кроме того, не принимайте всплески серьезно ... – akrun