如何完全洗牌R中的列
How to completely shuffle column in R
我想随机打乱 R 中的一列数字,并作为新列追加 3 次。但我希望每次都将每个元素改组到一个新行。
假设如果 1 为 c2 转到 r3,它不能为 c3
到达 r1 或 r3
sample <- data.frame(1:4)
基本上生成这样的东西,但我想用于更大的数据,
c1是原来的
||||||c1| c2 |c3 |c4\
---------------\
r1 | 1 | 4 | 3 | 2\
r2 | 2 | 1 | 4 | 3\
r3 | 3 | 2 | 1 | 4\
r4 | 4 | 3 | 2 | 1
有趣的问题。这是一个不优雅的解决方案,解决了数字 1 到 4,但适用于任何初始值集。
它依次构建每一列。在每一步,它首先随机洗牌第一列中的数字。然后它确保没有逐行匹配,所以正如你所说,如果 1 为 c2 转到 r3,它不能为 c3 到达 r1 或 r3。
library(dplyr)
initial_values <- 1:4
cs <- tibble(c1 = initial_values,
c2 = 1,
c3 = 1,
c4 = 1)
while(any(cs$c1 == cs$c2)){
cs <- cs %>%
mutate(c2 = sample(c1, length(c1)))
}
while(any(cs$c3 == cs$c2 | cs$c3 == cs$c1)){
cs <- cs %>%
mutate(c3 = sample(c1, length(c1)))
}
while(any(cs$c4 == cs$c3 | cs$c4 == cs$c2 | cs$c4 == cs$c1)){
cs <- cs %>%
mutate(c4 = sample(c1, length(c1)))
}
结果如下:
# A tibble: 4 x 4
c1 c2 c3 c4
<int> <int> <int> <int>
1 1 4 2 3
2 2 3 1 4
3 3 2 4 1
4 4 1 3 2
经过一番思考,我相信您可以将其扩展为适用于任意数量列的通用函数。
最佳使用方法取决于您有多少行和多少列(以及 c1 中是否存在重复值)。
假设行数比所需的列数(迭代)多得多,合理的方法可能是随机生成排列,丢弃任何产生重复的东西:
N = 100000
ncols = 3
sample = data.frame(c1=1:N)
orderings = data.frame(c1 = 1:N) # Initial ordering
reordering = orderings[,1]
c = 1
no_generated = 0
while (c <= ncols){
while (sum(reordering == orderings) > 0){ # check for any repetitions
print(sum(reordering == orderings))
reordering = order(runif(N)) # random reordering
no_generated = no_generated + 1
}
c = c + 1
orderings[[paste0('c',c)]] = reordering
}
cat(sprintf('%d permutations generated\n', no_generated))
print(sum(duplicated(orderings,MARGIN=2))) # Should be zero
如果行数更接近所需的列数,则更智能的组合方法可能更好。
我用 while 循环解决了这个问题。
我知道循环条件有点长,但就我而言,我知道我只需要 3 个新列,所以还不错。我想如果列数未知,我需要更多修改
data = c(1:5)
data_1 = c(1:5)
data_2 = c(1:5)
data_3 = c(1:5)
while(any(data == data_1|data == data_2|data == data_3|data_1 == data_2|data_1 == data_3|data_2 == data_3)){
data_1 = c(sample(data,5, replace = FALSE))
data_2 = c(sample(data,5, replace = FALSE))
data_3 = c(sample(data,5, replace = FALSE))
}
df = data.frame(data,data_1,data_2,data_3)
df
我想随机打乱 R 中的一列数字,并作为新列追加 3 次。但我希望每次都将每个元素改组到一个新行。 假设如果 1 为 c2 转到 r3,它不能为 c3
到达 r1 或 r3sample <- data.frame(1:4)
基本上生成这样的东西,但我想用于更大的数据,
c1是原来的
||||||c1| c2 |c3 |c4\
---------------\
r1 | 1 | 4 | 3 | 2\
r2 | 2 | 1 | 4 | 3\
r3 | 3 | 2 | 1 | 4\
r4 | 4 | 3 | 2 | 1
有趣的问题。这是一个不优雅的解决方案,解决了数字 1 到 4,但适用于任何初始值集。
它依次构建每一列。在每一步,它首先随机洗牌第一列中的数字。然后它确保没有逐行匹配,所以正如你所说,如果 1 为 c2 转到 r3,它不能为 c3 到达 r1 或 r3。
library(dplyr)
initial_values <- 1:4
cs <- tibble(c1 = initial_values,
c2 = 1,
c3 = 1,
c4 = 1)
while(any(cs$c1 == cs$c2)){
cs <- cs %>%
mutate(c2 = sample(c1, length(c1)))
}
while(any(cs$c3 == cs$c2 | cs$c3 == cs$c1)){
cs <- cs %>%
mutate(c3 = sample(c1, length(c1)))
}
while(any(cs$c4 == cs$c3 | cs$c4 == cs$c2 | cs$c4 == cs$c1)){
cs <- cs %>%
mutate(c4 = sample(c1, length(c1)))
}
结果如下:
# A tibble: 4 x 4
c1 c2 c3 c4
<int> <int> <int> <int>
1 1 4 2 3
2 2 3 1 4
3 3 2 4 1
4 4 1 3 2
经过一番思考,我相信您可以将其扩展为适用于任意数量列的通用函数。
最佳使用方法取决于您有多少行和多少列(以及 c1 中是否存在重复值)。
假设行数比所需的列数(迭代)多得多,合理的方法可能是随机生成排列,丢弃任何产生重复的东西:
N = 100000
ncols = 3
sample = data.frame(c1=1:N)
orderings = data.frame(c1 = 1:N) # Initial ordering
reordering = orderings[,1]
c = 1
no_generated = 0
while (c <= ncols){
while (sum(reordering == orderings) > 0){ # check for any repetitions
print(sum(reordering == orderings))
reordering = order(runif(N)) # random reordering
no_generated = no_generated + 1
}
c = c + 1
orderings[[paste0('c',c)]] = reordering
}
cat(sprintf('%d permutations generated\n', no_generated))
print(sum(duplicated(orderings,MARGIN=2))) # Should be zero
如果行数更接近所需的列数,则更智能的组合方法可能更好。
我用 while 循环解决了这个问题。 我知道循环条件有点长,但就我而言,我知道我只需要 3 个新列,所以还不错。我想如果列数未知,我需要更多修改
data = c(1:5)
data_1 = c(1:5)
data_2 = c(1:5)
data_3 = c(1:5)
while(any(data == data_1|data == data_2|data == data_3|data_1 == data_2|data_1 == data_3|data_2 == data_3)){
data_1 = c(sample(data,5, replace = FALSE))
data_2 = c(sample(data,5, replace = FALSE))
data_3 = c(sample(data,5, replace = FALSE))
}
df = data.frame(data,data_1,data_2,data_3)
df