Использование цикла для создания матриц в 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)