Использование цикла для создания матриц в R

Я пытаюсь провести кросс-проверку по принципу "оставь один раз" для относительно небольшого набора данных (n = 22, p = 17) для линейной регрессии, сделанной по алгоритму LARS. По сути, мне нужно создать n матриц стандартизированных данных (каждый столбец состоит из записей, центрированных по среднему и стандартизированных SD столбца).

Я никогда раньше не использовал списки, но был бы открыт для составления списков, если можно манипулировать / стандартизировать столбцы разных матриц.

Вот что я попробовал в R:

for (i in 1:n)
{
  x.standardized.i <- matrix(data = NA, nrow = (n-1), ncol = p)  #creates n matrices, all n-1 x p
  for (j in 1:p)
  {
    x.standardized.i[,j] <- ((x[-i,j]-mean(x[-i,j]))/sd(x[-i,j])) #and standardizes the p variables with the ith row missing in each n matrix (i increments from 1 to n)
  }
}

Я не уверен, что смогу поделиться данными, так как они связаны с оценками класса, но когда я запускаю код, он проходит цикл и останавливается, назначая стандартизированную матрицу с отсутствующей последней строкой как x.standardized.i,

1 ответ

Решение

Вы можете сделать это довольно просто с sapply а также scale:

# Create dummy data
m <- matrix(runif(200), ncol=10)

# Leave each row out in turn, and scale each column
A <- sapply(seq_len(nrow(m)), function(i) scale(m[-i, ]), simplify='array')

По умолчанию, scale центрирует каждый столбец по его среднему значению и делит его по sd.

В приведенном выше примере вы получите массив из 19 строк, 10 столбцов и 20 срезов.

Чтобы получить доступ к определенным фрагментам (то есть кросс-валидационным тренировочным сгибам), вы можете использовать подмножество следующим образом

A[,, 1] # all rows, all cols, first slice
A[,, 10] # all rows, all cols, tenth slice

Чтобы подтвердить, что столбцы центрированы по их среднему значению и стандартизированы одним sd:

apply(A, c(2, 3), mean)
apply(A, c(2, 3), sd)
Другие вопросы по тегам