假设我有一个像这样的 data.frame:
set.seed(123)
df <- data.frame(a=rnorm(10, 0,1), b=rnorm(10,1,2), c=rnorm(10, 2, 1),
x=rnorm(10, 1,2), y=rnorm(10,2,3), z=rnorm(10, 3, 4))
# a b c x y z
#1 -0.56047565 3.44816359 0.9321763 1.8529284 -0.08412094 4.013274
#2 -0.23017749 1.71962765 1.7820251 0.4098570 1.37624817 2.885813
#3 1.55870831 1.80154290 0.9739956 2.7902513 -1.79618905 2.828518
#4 0.07050839 1.22136543 1.2711088 2.7562670 8.50686790 8.474409
#5 0.12928774 -0.11168227 1.3749607 2.6431622 5.62388599 2.096916
#6 1.71506499 4.57382627 0.3133067 2.3772805 -1.36932575 9.065882
#7 0.46091621 1.99570096 2.8377870 2.1078353 0.79134549 -3.195011
#8 -1.26506123 -2.93323431 2.1533731 0.8761766 0.60003394 5.338455
#9 -0.68685285 2.40271180 0.8618631 0.3880747 4.33989536 3.495417
#10 -0.44566197 0.05441718 3.2538149 0.2390580 1.74989280 3.863766
Run Code Online (Sandbox Code Playgroud)
如何重新排序列以获得以下内容?
# a x b y c z
#1 -0.56047565 1.8529284 3.44816359 -0.08412094 0.9321763 4.013274
#2 -0.23017749 0.4098570 1.71962765 1.37624817 1.7820251 2.885813
#3 1.55870831 2.7902513 1.80154290 -1.79618905 0.9739956 2.828518
#4 0.07050839 2.7562670 1.22136543 8.50686790 1.2711088 8.474409
#5 0.12928774 2.6431622 -0.11168227 5.62388599 1.3749607 2.096916
#6 1.71506499 2.3772805 4.57382627 -1.36932575 0.3133067 9.065882
#7 0.46091621 2.1078353 1.99570096 0.79134549 2.8377870 -3.195011
#8 -1.26506123 0.8761766 -2.93323431 0.60003394 2.1533731 5.338455
#9 -0.68685285 0.3880747 2.40271180 4.33989536 0.8618631 3.495417
#10 -0.44566197 0.2390580 0.05441718 1.74989280 3.2538149 3.863766
Run Code Online (Sandbox Code Playgroud)
Hen*_*rik 10
使用模 ( %%)
d2 = df[ , order((seq_along(df) - 1) %% (ncol(df) / 2))]
names(d2)
# [1] "a" "x" "b" "y" "c" "z"
Run Code Online (Sandbox Code Playgroud)
要使其同时适用于偶数和奇数列,请ceiling在除数中使用:
df_odd = df[-6]
d2 = df_odd[ , order((seq_along(df_odd) - 1) %% ceiling(ncol(df) / 2))]
names(d2)
# [1] "a" "x" "b" "y" "c"
Run Code Online (Sandbox Code Playgroud)
旁注:因为 OP 提到他们有超过 100 多个列,所以可能需要考虑data.table::setcolorder,它会在不复制数据的情况下对列进行重新排序:
library(data.table)
setDT(df)
setcolorder(df, order((seq_along(df) - 1) %% ceiling(ncol(df) / 2)))
Run Code Online (Sandbox Code Playgroud)
我们可以使用以下函数生成密钥洗牌索引。n它同时处理奇数/偶数,而不需要if(),取代了我最初的答案,即分别处理奇数和n偶数。它也比使用 的替代方案sequence()更简洁。
ShufInd <- function (n) matrix(seq_len(n + n %% 2), , 2, TRUE)[1:n]
ShufInd(6)
#[1] 1 4 2 5 3 6
ShufInd(5)
#[1] 1 4 2 5 3
Run Code Online (Sandbox Code Playgroud)
打乱向量(原子或列表)或长度为 的数据帧n:
## OP's data frame
df[ShufInd(length(df))]
## drop the last column they try again
df <- df[-6]
df[ShufInd(length(df))]
## an atomic vector
x <- letters[1:5]
x[ShufInd(length(x))]
## a list
x <- as.list(x)
x[ShufInd(length(x))]
Run Code Online (Sandbox Code Playgroud)
打乱矩阵的列:
mat <- matrix(1:10, 2, 5)
mat[, ShufInd(ncol(mat))]
Run Code Online (Sandbox Code Playgroud)
Henrik的答案也是一个统一的方法,可以写成:
Henrik <- function (n) order(seq(0, n - 1) %% ceiling(n / 2))
Run Code Online (Sandbox Code Playgroud)