在循环中切换第一个元素和最后一个元素
Switching the first element with the last one in a loop
R 中是否有一个函数可以切换向量中的第一个元素和最后一个元素?我有一个需要重新排序的 for 循环。来自:
months = seq(1:12)
[1] 1 2 3 4 5 6 7 8 9 10 11 12
我想要:
[1] 12 1 2 3 4 5 6 7 8 9 10 11
然后又是:
[1] 11 12 1 2 3 4 5 6 7 8 9 10
...
直到第12位。
恐怕你得想出一个自制的函数,像这样:
rotate <- function(v,i=1) {
i <- i %% length(v)
if (i==0) return(v)
v[c(seq(i+1,length(v)),seq(i))]
}
几个例子:
v <- seq(12)
rotate(v,1)
# [1] 2 3 4 5 6 7 8 9 10 11 12 1
rotate(v,-1)
# [1] 12 1 2 3 4 5 6 7 8 9 10 11
如果需要矩阵输出
cbind(c(months),embed(c(months, months), 12)[-13,-12])
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,] 1 12 11 10 9 8 7 6 5 4 3 2
# [2,] 2 1 12 11 10 9 8 7 6 5 4 3
# [3,] 3 2 1 12 11 10 9 8 7 6 5 4
# [4,] 4 3 2 1 12 11 10 9 8 7 6 5
# [5,] 5 4 3 2 1 12 11 10 9 8 7 6
# [6,] 6 5 4 3 2 1 12 11 10 9 8 7
# [7,] 7 6 5 4 3 2 1 12 11 10 9 8
# [8,] 8 7 6 5 4 3 2 1 12 11 10 9
# [9,] 9 8 7 6 5 4 3 2 1 12 11 10
#[10,] 10 9 8 7 6 5 4 3 2 1 12 11
#[11,] 11 10 9 8 7 6 5 4 3 2 1 12
#[12,] 12 11 10 9 8 7 6 5 4 3 2 1
或@Marat Talipov 建议的另一种方法
z <- length(months)
i <- rep(seq(z),z) + rep(seq(z),each=z) - 1
matrix(months[ifelse(i>z,i-z,i)],ncol=z)
您还可以使用 tail
和 head
函数:
x = c(tail(x,n), head(x,-n))
并修改n
旋转n
次
permute 包可以为您做到这一点:
ap <- allPerms(length(months),
control = how(within = Within(type = "series"),
observed = TRUE))
ap[rev(seq_len(nrow(ap))), ]
(由于 allPerms()
的工作方式,我们需要颠倒行的顺序,这就是最后一行的作用。)
这给出:
> ap[rev(seq_len(nrow(ap))), ]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 2 3 4 5 6 7 8 9 10 11 12
[2,] 12 1 2 3 4 5 6 7 8 9 10 11
[3,] 11 12 1 2 3 4 5 6 7 8 9 10
[4,] 10 11 12 1 2 3 4 5 6 7 8 9
[5,] 9 10 11 12 1 2 3 4 5 6 7 8
[6,] 8 9 10 11 12 1 2 3 4 5 6 7
[7,] 7 8 9 10 11 12 1 2 3 4 5 6
[8,] 6 7 8 9 10 11 12 1 2 3 4 5
[9,] 5 6 7 8 9 10 11 12 1 2 3 4
[10,] 4 5 6 7 8 9 10 11 12 1 2 3
[11,] 3 4 5 6 7 8 9 10 11 12 1 2
[12,] 2 3 4 5 6 7 8 9 10 11 12 1
从技术上讲,这只有效,因为 months
是向量 1:12
而 allPerms()
returns 是您要排列的事物的索引的排列矩阵。对于不同的输入,使用 ap
索引到你想要排列的东西
perms <- ap
perms[] <- months[ap[rev(seq_len(nrow(ap))), ]]
perms
R 中是否有一个函数可以切换向量中的第一个元素和最后一个元素?我有一个需要重新排序的 for 循环。来自:
months = seq(1:12)
[1] 1 2 3 4 5 6 7 8 9 10 11 12
我想要:
[1] 12 1 2 3 4 5 6 7 8 9 10 11
然后又是:
[1] 11 12 1 2 3 4 5 6 7 8 9 10
... 直到第12位。
恐怕你得想出一个自制的函数,像这样:
rotate <- function(v,i=1) {
i <- i %% length(v)
if (i==0) return(v)
v[c(seq(i+1,length(v)),seq(i))]
}
几个例子:
v <- seq(12)
rotate(v,1)
# [1] 2 3 4 5 6 7 8 9 10 11 12 1
rotate(v,-1)
# [1] 12 1 2 3 4 5 6 7 8 9 10 11
如果需要矩阵输出
cbind(c(months),embed(c(months, months), 12)[-13,-12])
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,] 1 12 11 10 9 8 7 6 5 4 3 2
# [2,] 2 1 12 11 10 9 8 7 6 5 4 3
# [3,] 3 2 1 12 11 10 9 8 7 6 5 4
# [4,] 4 3 2 1 12 11 10 9 8 7 6 5
# [5,] 5 4 3 2 1 12 11 10 9 8 7 6
# [6,] 6 5 4 3 2 1 12 11 10 9 8 7
# [7,] 7 6 5 4 3 2 1 12 11 10 9 8
# [8,] 8 7 6 5 4 3 2 1 12 11 10 9
# [9,] 9 8 7 6 5 4 3 2 1 12 11 10
#[10,] 10 9 8 7 6 5 4 3 2 1 12 11
#[11,] 11 10 9 8 7 6 5 4 3 2 1 12
#[12,] 12 11 10 9 8 7 6 5 4 3 2 1
或@Marat Talipov 建议的另一种方法
z <- length(months)
i <- rep(seq(z),z) + rep(seq(z),each=z) - 1
matrix(months[ifelse(i>z,i-z,i)],ncol=z)
您还可以使用 tail
和 head
函数:
x = c(tail(x,n), head(x,-n))
并修改n
旋转n
次
permute 包可以为您做到这一点:
ap <- allPerms(length(months),
control = how(within = Within(type = "series"),
observed = TRUE))
ap[rev(seq_len(nrow(ap))), ]
(由于 allPerms()
的工作方式,我们需要颠倒行的顺序,这就是最后一行的作用。)
这给出:
> ap[rev(seq_len(nrow(ap))), ]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 2 3 4 5 6 7 8 9 10 11 12
[2,] 12 1 2 3 4 5 6 7 8 9 10 11
[3,] 11 12 1 2 3 4 5 6 7 8 9 10
[4,] 10 11 12 1 2 3 4 5 6 7 8 9
[5,] 9 10 11 12 1 2 3 4 5 6 7 8
[6,] 8 9 10 11 12 1 2 3 4 5 6 7
[7,] 7 8 9 10 11 12 1 2 3 4 5 6
[8,] 6 7 8 9 10 11 12 1 2 3 4 5
[9,] 5 6 7 8 9 10 11 12 1 2 3 4
[10,] 4 5 6 7 8 9 10 11 12 1 2 3
[11,] 3 4 5 6 7 8 9 10 11 12 1 2
[12,] 2 3 4 5 6 7 8 9 10 11 12 1
从技术上讲,这只有效,因为 months
是向量 1:12
而 allPerms()
returns 是您要排列的事物的索引的排列矩阵。对于不同的输入,使用 ap
索引到你想要排列的东西
perms <- ap
perms[] <- months[ap[rev(seq_len(nrow(ap))), ]]
perms