Матрица комбинации последовательностей в R - PullRequest
0 голосов
/ 12 июня 2018

Я хочу создать матрицу для 5 переменных, чтобы каждая переменная принимала значение из seq(from = 0, to = 1, length.out = 500) и rowSums(data) = 1.

Другими словами, мне интересно, как создать матрицу, котораяпоказывает все возможные комбинации чисел с суммой каждого row = 1.

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

Вот итерационное решение с использованием циклов.Дает вам все возможные перестановки чисел, складывающихся до 1, с расстоянием между ними, кратным N. Идея здесь состоит в том, чтобы взять все числа от 0 до 1 (с расстоянием, кратным N между ними), затем для каждогоодин включает в новый столбец все числа, которые при добавлении не идут выше 1. Промыть и повторить, за исключением последней итерации, в которой вы только добавляете числа, которые завершают строку, сумму строки.

Как и люди, указанные в комментариях, если вы хотите N = 1/499 *, это даст вам действительно очень большую матрицу.Я заметил, что для N = 1/200 это заняло около 2, 3 минут, поэтому, вероятно, для N = 1/499 это заняло бы слишком много времени.

*seq(from = 0, to = 1, length.out = 500) - это то же самое, что и seq(from = 0, to = 1, by = 1/499)

N = 1/2
M = 5

x1 = seq(0, 1, by = N)

df = data.frame(x1)

for(i in 1:(M-2)){

  x_next = sapply(rowSums(df), function(x){seq(0, 1-x, by = N)})
  df = data.frame(sapply(df, rep, sapply(x_next,length)))
  df = cbind(df, unlist(x_next))

}

x_next = sapply(rowSums(df), function(x){1-x})
df = sapply(df, rep, sapply(x_next,length))
df = data.frame(df)
df = cbind(df, unlist(x_next))

> df
    x1 unlist.x_next. unlist.x_next..1 unlist.x_next..2 unlist(x_next)
1  0.0            0.0              0.0              0.0            1.0
2  0.0            0.0              0.0              0.5            0.5
3  0.0            0.0              0.0              1.0            0.0
4  0.0            0.0              0.5              0.0            0.5
5  0.0            0.0              0.5              0.5            0.0
6  0.0            0.0              1.0              0.0            0.0
7  0.0            0.5              0.0              0.0            0.5
8  0.0            0.5              0.0              0.5            0.0
9  0.0            0.5              0.5              0.0            0.0
10 0.0            1.0              0.0              0.0            0.0
11 0.5            0.0              0.0              0.0            0.5
12 0.5            0.0              0.0              0.5            0.0
13 0.5            0.0              0.5              0.0            0.0
14 0.5            0.5              0.0              0.0            0.0
15 1.0            0.0              0.0              0.0            0.0
0 голосов
/ 12 июня 2018

Это именно то, для чего сделана упаковка partitions.По сути, ОП ищет все возможные комбинации из 5 целых чисел, которые составляют 499. Этого легко достичь с помощью restrictedparts:

system.time(combsOne <- t(as.matrix(restrictedparts(499, 5))) / 499)
 user  system elapsed 
1.635   0.867   2.502 


head(combsOne)
         [,1]        [,2] [,3] [,4] [,5]
[1,] 1.000000 0.000000000    0    0    0
[2,] 0.997996 0.002004008    0    0    0
[3,] 0.995992 0.004008016    0    0    0
[4,] 0.993988 0.006012024    0    0    0
[5,] 0.991984 0.008016032    0    0    0
[6,] 0.989980 0.010020040    0    0    0

tail(combsOne)
                 [,1]      [,2]      [,3]      [,4]      [,5]
[22849595,] 0.2024048 0.2004008 0.2004008 0.2004008 0.1963928
[22849596,] 0.2064128 0.1983968 0.1983968 0.1983968 0.1983968
[22849597,] 0.2044088 0.2004008 0.1983968 0.1983968 0.1983968
[22849598,] 0.2024048 0.2024048 0.1983968 0.1983968 0.1983968
[22849599,] 0.2024048 0.2004008 0.2004008 0.1983968 0.1983968
[22849600,] 0.2004008 0.2004008 0.2004008 0.2004008 0.1983968

И поскольку мы имеем дело с числовыми значениями, мы не можем получить точныеточность, однако мы можем получить точность станка:

all(rowSums(combsOne) == 1)
[1] FALSE

all((rowSums(combsOne) - 1) < .Machine$double.eps)
[1] TRUE

Более 22 миллионов результатов:

row(combsOne)
[1] 22849600
0 голосов
/ 12 июня 2018

Если я правильно понял, это может привести вас как минимум к правильному пути.

# Parameters
len_vec = 500 # vector length
num_col = 5 # number of columns

# Creating the values for the matrix using rational numbers between 0 and 1
values <- runif(len_vec*num_col)

# Creating matrix
mat <- matrix(values,ncol = num_col,byrow = T)

# ROunding the matrix to create only 0s and 1s
mat <- round(mat)

# Calculating the sum per row
apply(mat,1,sum)
...