Агрегировать случайным образом выбранные столбцы для итерационно больших размеров бинов - PullRequest
2 голосов
/ 25 сентября 2019

У меня есть такая матрица:

mat<- matrix(c(1,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,
2,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,
1,1,0,0,0,0,0,0,1,0,1,2,1,0,0,0), nrow=16, ncol=6)
dimnames(mat)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
      c("1", "2", "3", "4", "5", "6"))

Я хочу сгруппировать столбцы или столбцы, а затем объединить данные для каждой группы.Повторите выборку для корзины размером x, n раз.Этот процесс будет повторяться для размеров бинов х + 1.

Для первой итерации два случайных столбца сгруппированы.Я хотел бы сделать выборку без замены, чтобы комбинация из двух столбцов не выбиралась дважды (однако столбец можно использовать дважды, если он связан с другим столбцом).Агрегация определяется как вычисление сумм строк для столбцов с столбцами.Агрегированные результаты будут добавлены в виде нового столбца в матрицу результатов для этого размера ячейки.Количество столбцов в матрице результатов будет ограничено количеством случайно выбранных бинов.

Размер корзины продолжает увеличиваться.Для следующей итерации размер ячейки увеличивается до 3, так что объединяются 3 случайно выбранных столбца.Агрегированные данные будут помещены в другую матрицу результатов.Этот процесс будет продолжаться до тех пор, пока размер бина не станет равным размеру фрейма данных, и в этом случае повторная выборка невозможна.Все матрицы результатов будут помещены в список матриц.

Ниже приведен ожидаемый результат resultList для первых двух размеров бинов с учетом приведенной выше матрицы.

# Bin size =2 
# The randomly sampled columns are columns 1&2, 2&3, 3&4, 4&5, 5&6. 
mat1<- matrix( c(3,0,0,0,1,0,1,0,0,0,0,0,0,0,2,0,
     2,0,1,1,2,0,0,0,0,0,0,0,0,0,1,0,
     0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
     0,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,
     1,1,0,0,1,0,0,1,1,1,2,2,1,1,0,1), nrow=16)
 dimnames(mat1)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
          c("1_2", "2_3", "3_4", "4_5", "5_6"))

 # Bin size= 3
 # The randomly selected columns to be joined are columns 1,2&3, 
 # 2,3&4, 3,4&5, 4,5&6. 
 mat3<- matrix( c(3,0,1,1,2,0,1,0,0,0,0,0,0,0,3,0,
     2,1,1,1,2,1,0,0,0,0,0,0,0,0,1,0,
     0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,
     1,2,0,0,1,1,0,1,1,1,2,2,1,1,0,1), nrow=16)
dimnames(mat8)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
          c("1_2_3", "2_3_4", "3_4_5", "4_5_6"))

resultList<-list(mat1, mat2)

Я разместил аналогичный вопрос для альтернативного метода биннинга здесь: Столбцы бинов и агрегированные данные с использованием случайной выборки с заменой для итеративно больших размеров бинов

Здесьмоя попытка сгруппировать случайно выбранные столбцы и поместить результаты для каждого размера бина в список матриц.Я попытался выбрать j случайные столбцы, используя sample, сделать rowSums и удалить выбранные j парные столбцы, чтобы они не повторялись в следующей итерации:

lapply(seq_len(ncol(mat) - 1), function(j) do.call(cbind, 
lapply(sample(ncol(mat) - j, size= ), function(i) rowSums(mat[, i:(i - j)]))))

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Исходя из того, сколько столбцов вы хотите получить в конечном выводе, мы можем изменить подход, но в настоящее время это дает все возможные комбинации.

#Get column names of the matrices
all_cols <- colnames(mat)

#Select bin value from 2:ncol(mat)
total_out <- lapply(seq_len(ncol(mat))[-1], function(j) {
      #Create all combinations taking j items at a time
      temp <- combn(all_cols, j, function(x) 
              #Take rowSums for the current combination
              #Also paste column names to assign column names later
              list(rowSums(mat[, x]), paste0(x, collapse = "_")), simplify = FALSE)
      #Combine rowSums matrix 
      new_mat <- sapply(temp, `[[`, 1)
      #Assign column names
      colnames(new_mat) <- sapply(temp, `[[`, 2)
      #Return new matrix
      new_mat
})

Текущий вывод выглядит как

total_out
#[[1]]
#  1_2 1_3 1_4 1_5 1_6 2_3 2_4 2_5 2_6 3_4 3_5 3_6 4_5 4_6 5_6
#a   3   1   1   1   2   2   2   2   3   0   0   1   0   1   1
#c   0   0   1   0   1   0   1   0   1   1   0   1   1   2   1
#f   0   1   0   0   0   1   0   0   0   1   1   1   0   0   0
#h   0   1   0   0   0   1   0   0   0   1   1   1   0   0   0
#i   1   1   0   1   0   2   1   2   1   1   2   1   1   0   1
#j   0   0   1   0   0   0   1   0   0   1   0   0   1   1   0
#l   1   1   1   1   1   0   0   0   0   0   0   0   0   0   0
#m   0   0   0   1   0   0   0   1   0   0   1   0   1   0   1
#p   0   0   0   0   1   0   0   0   1   0   0   1   0   1   1
#q   0   0   0   1   0   0   0   1   0   0   1   0   1   0   1
#s   0   0   0   1   1   0   0   1   1   0   1   1   1   1   2
#t   0   0   0   0   2   0   0   0   2   0   0   2   0   2   2
#u   0   0   0   0   1   0   0   0   1   0   0   1   0   1   1
#v   0   0   0   1   0   0   0   1   0   0   1   0   1   0   1
#x   3   2   2   2   2   1   1   1   1   0   0   0   0   0   0
#z   0   0   0   1   0   0   0   1   0   0   1   0   1   0   1
#...
#....
#....
#[[5]]
#  1_2_3_4_5_6
#a           4
#c           2
#f           1
#h           1
#i           3
#j           1
#l           1
#m           1
#p           1
#q           1
#s           2
#t           2
#u           1
#v           1
#x           3
#z           1

Обратите внимание, что в total_out имеется всего 5 (ncol - 1) матриц с количеством столбцов, равным

length(total_out)
#[1] 5

sapply(total_out, ncol)
#[1] 15 20 15  6  1

. Чтобы случайным образом выбрать C/2 столбцы, мы можем сделать

no_col <- ncol(mat)

lapply(total_out, function(x) {
   nc <- ncol(x)
   if (nc != no_col) 
     x[, sample(nc, ceiling(nc/2))]
   else
     x
})
0 голосов
/ 29 сентября 2019

Это непосредственно выборки k столбцов случайным образом и выводит результат в list матриц:

set.seed(123)
#for i = 2:((ncol(mat))-1)
lapply(seq_len(ncol(mat)-1)[-1], 
       function(k) {
       #generate combos 
         all_combos <- combn(ncol(mat), k)
       #select some of the combos at random
         combos <- all_combos[, sample(ncol(all_combos), ncol(mat) - k + 1)]

       #subset the original matrix take the rowSums
         mat_return <- apply(combos, 2, function(cols) rowSums(mat[, cols]))
       #name the matrix
         colnames(mat_return) <- apply(combos, 2, paste0, collapse = '_')

         return(mat_return)
       }
  )   

[[1]]
  5_6 1_4 4_6 3_4 1_3
a   1   1   1   0   1
c   1   1   2   1   0
f   0   0   0   1   1
h   0   0   0   1   1
i   1   0   0   1   1
j   0   1   1   1   0
l   0   1   0   0   1
m   1   0   0   0   0
p   1   0   1   0   0
q   1   0   0   0   0
s   2   0   1   0   0
t   2   0   2   0   0
u   1   0   1   0   0
v   1   0   0   0   0
x   0   2   0   0   2
z   1   0   0   0   0

[[2]]
  2_3_4 1_3_4 2_4_5 3_5_6
a     2     1     2     1
c     1     1     1     1
f     1     1     0     1
h     1     1     0     1
i     2     1     2     2
j     1     1     1     0
l     0     1     0     0
m     0     0     1     1
p     0     0     0     1
q     0     0     1     1
s     0     0     1     2
t     0     0     0     2
u     0     0     0     1
v     0     0     1     1
x     1     2     1     0
z     0     0     1     1

[[3]]
  1_2_3_6 2_3_4_5 1_3_5_6
a       4       2       2
c       1       1       1
f       1       1       1
h       1       1       1
i       2       3       2
j       0       1       0
l       1       0       1
m       0       1       1
p       1       0       1
q       0       1       1
s       1       1       2
t       2       0       2
u       1       0       1
v       0       1       1
x       3       1       2
z       0       1       1

[[4]]
  1_2_4_5_6 1_2_3_4_5
a         4         3
c         2         1
f         0         1
h         0         1
i         2         3
j         1         1
l         1         1
m         1         1
p         1         0
q         1         1
s         2         1
t         2         0
u         1         0
v         1         1
x         3         3
z         1         1    
...