Создайте l oop, чтобы использовать увеличивающуюся часть данных в R в качестве входных данных для функции - PullRequest
1 голос
/ 20 февраля 2020

Я использую первый основной компонент из анализа PCA в качестве объясняющей переменной в модели прогнозирования, которая делает рекурсивные прогнозы с использованием фильтрации Калмана. Другими словами, в каждый момент времени модель обновляется и выдает новый прогноз на основе нового наблюдения, включенного в модель. Поскольку PCA использует данные всех наблюдений, включенных в модель, для своих вычислений, мне нужно рекурсивно выполнять также PCA, используя только наблюдения до того момента, когда я прогнозирую (в противном случае результат PCA может раскрыть информацию о и помогите модели дать более точный ответ, чем в противном случае). Я думаю, что oop может быть решением, но я борюсь с тем, как сформулировать код.

В качестве более конкретного c примера рассмотрим, есть ли у меня следующий data.frame

data <- as.data.frame(rbind(c(6,15,23),c(9,11,22), c(7,13,23), c(6,12,25),c(7,13,23)))
names(data) <- c("V1","V2","V3")

> data
  V1 V2 V3
1  6 15 23
2  9 11 22
3  7 13 23
4  6 12 25
5  7 13 23

На каждую дату наблюдения я буду sh запускать PCA (функция prcomp() из пакета stats) для всех наблюдений вплоть до этого наблюдения, включая это наблюдение. Поэтому я хочу сначала запустить PCA для двух первых наблюдений

pca2 <- prcomp(data[1:2,], scale = TRUE)

Далее я хочу запустить PCA с первым, вторым и третьим наблюдением в качестве ввода

pca3 <- prcomp(data[1:3,], scale = TRUE)

далее я хочу запускать PCA с первым, вторым, третьим и четвертым наблюдением в качестве входных данных

pca4 <- prcomp(data[1:4,], scale = TRUE)

и т. д. до последнего запуска PCA, который включает все наблюдения в кадре данных. Для каждого из этих «прогонов» PCA я извлекаю последнее значение (хотя для pca2 я использую и первое, и второе значения) первого основного компонента (PC1) и объединяю их в окончательный вариант. фрейм данных, где каждое ежемесячное наблюдение является последним значением первого основного компонента результатов PCA для каждого из прогонов.

Выводы основного компонента:

> my_pca2 <- as.data.frame(pca2$x)
> my_pca2
        PC1           PC2
1 -1.224745 -5.551115e-17
2  1.224745  5.551115e-17

> my_pca3 <- as.data.frame(pca3$x)
> my_pca3
         PC1        PC2          PC3
1 -1.4172321 -0.2944338 6.106227e-16
2  1.8732448 -0.1215046 3.330669e-16
3 -0.4560127  0.4159384 4.163336e-16

> my_pca4 <- as.data.frame(pca4$x)
> my_pca4
          PC1         PC2          PC3
1 -1.03030993 -1.10154914  0.015457199
2  2.00769890  0.07649216  0.011670433
3  0.03301806 -0.24226508 -0.033461874
4 -1.01040702  1.26732205  0.006334242

Итак, я хочу, чтобы мой final output чтобы быть фреймом данных, похожим на

>final.output
         PC1
1  -1.224745
2   1.224745
3 -0.4560127
4 -1.01040702

Комментарий: да, с двумя первыми значениями это выглядит немного странно, но, пожалуйста, не обращайте на это слишком много внимания. Моя точка зрения заключается в том, что я sh хочу построить кадр данных, который состоит из последнего вычисленного значения для первого основного компонента для каждого из прогонов PCA.

Я думаю, что for.l oop может быть лучшим решением здесь, но мне не удалось найти какие-либо темы, которые могли бы приблизить меня к решению кодирования. Как я могу заставить l oop использовать увеличивающийся объем данных в расчетах? У кого-нибудь есть предложения / советы / ссылки? Любая помощь в этом очень ценится!

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

У меня был очень похожий подход.

PCA <- vector("list", length=nrow(data)-1)
for(i in 1:(nrow(data)-1)) {
  if(i==1) j <- 1:2 else j<-i+1
  PCA[[i]] <- as.data.frame(prcomp(data[1:(1+i),], scale = TRUE)$x)[j, 1]
}

unlist(PCA)
0 голосов
/ 20 февраля 2020

Вы можете использовать для l oop. Возможно, это не самое эффективное решение, но оно будет работать.

Сначала вы создаете пустой список для хранения результатов:

all_results <- list()

Затем вы повторяете число от 2 до числа ряды data с al oop. Для каждой итерации l oop выполните prcomp на data[1:i,]. Вы можете напрямую создать свой кадр данных pca и извлечь из него PC1 как вектор. Теперь вы сохраняете его в списке по индексу i - 1

for(i in 2:nrow(data))
{
  all_results[[i - 1]] <- as.data.frame(prcomp(data[1:i,], scale = TRUE)$x)$PC1
}

Теперь, чтобы извлечь все результаты, вы используете lapply (list apply), чтобы извлечь только последний элемент из каждого вектора PC1:

PC1 <- lapply(all_results, function(pca) pca[length(pca)] )

Теперь вы преобразуете их из списка отдельных элементов в вектор:

PC1 <- do.call("c", PC1)

Наконец, вы хотите вставить первое значение первого анализа обратно в начало этого вектор:

PC1 <- c(all_results[[1]][1], PC1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...