Ну, я не знаю, что вы имеете в виду под without using R functions
, так как почти все является функцией R, но вот решение, использующее только очень общий nrow()
(Количество строк матрицы), %%
(модуль) и seq_len
(эквивалентно 1:length(x)
за исключением того, что он работает лучше):
m <- matrix(1:40,,2,byrow=TRUE)
shift2 <- function(d, k) d[(seq_len(nrow(d))-k-1)%%(nrow(d))+1,]
shift2(m,5)
[,1] [,2]
[1,] 31 32
[2,] 33 34
[3,] 35 36
[4,] 37 38
[5,] 39 40
[6,] 1 2
[7,] 3 4
[8,] 5 6
[9,] 7 8
[10,] 9 10
[11,] 11 12
[12,] 13 14
[13,] 15 16
[14,] 17 18
[15,] 19 20
[16,] 21 22
[17,] 23 24
[18,] 25 26
[19,] 27 28
[20,] 29 30
Если вы подразумеваете под "нормальным программным кодом", что его не следует векторизовать, тогда вы хорошо изучаете либо неправильный язык, либо неправильный язык. Каждый раз, когда вы придумываете векторизованное решение вместо for
циклов, вы счастливы в R.
Но если вы действительно хотите сделать это с помощью циклов, то здесь точно та же самая функция без векторизации:
shift3 <- function(d, k)
{
out <- matrix(,nrow(d),ncol(d))
sorts <- (seq_len(nrow(d))-k-1)%%(nrow(d))+1
for (i in seq_len(nrow(d))) out[i,] <- d[sorts[i],]
return(out)
}
Доказательство того, что все они равны:
all(shift(m,5) == shift2(m,5) & shift2(m,5) == shift3(m,5))
[1] TRUE
EDIT:
На самом деле shift3()
там ВСЕ ЕЩЕ содержало много векторизаций, показывающих, насколько нативно это в R. Вот полностью невекторизованная версия:
shift3 <- function(d, k)
{
out <- matrix(,nrow(d),ncol(d))
sor <- numeric(1)
for (i in seq_len(nrow(d)))
{
if (i-k < 1) sor <- nrow(d)-k+i else sor <- i-k
for (j in seq_len(ncol(d))) out[i,j] <- d[sor,j]
}
return(out)
}