Количество столбцов, необходимое для достижения минимальной суммы, по строке - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть фрейм данных со строками в качестве времени и столбцами в качестве главных компонентов

(от ПК1 до ПК10).Пример можно найти в ответе, представленном здесь: Rolling PCA

Для каждой строки я хочу извлечь количество ПК, необходимое для достижения минимальной суммы 0,90.В таблице примера для каждой строки суммирование по трем столбцам дает минимум 0,90;поэтому я хочу извлечь номер 3 в отдельный столбец.В моем конкретном случае число столбцов, необходимое для достижения 0,9, зависит от строки.

Пример нужного мне результата приведен в последнем столбце (PC_N).

enter image description here

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

данные: (вы должны предоставить готовые данные)

set.seed(1337)    
df1 <- as.data.frame(matrix(runif(6*4), 6, 4))

код:

df1$PC_N <-
    apply(df1[1:4], 1, function(x) {which(cumsum(x) >= .9)[1]})

результат:

#         V1        V2         V3        V4 PC_N
#1 0.8455612 0.5753591 0.04045594 0.1168015    2
#2 0.3623455 0.7868502 0.34512398 0.5304800    2
#3 0.9092146 0.5210399 0.48515698 0.2770135    1
#4 0.6730770 0.1798602 0.45335329 0.7649627    3
#5 0.3068619 0.3963743 0.98232933 0.9653852    3
#6 0.2104455 0.7860896 0.42140667 0.7954002    2

подробнее:

apply(    # use apply over rows (1)
df1[1:4], # apply only on PC1 to PC4 (first to 4th col)
1,        # go row-wise
function(x) {
which(cumsum(x) >= .9)[1]  # get first index of the cummulated sum that is at least 0.9
})        # the end

убедитесь, что вы читаете далее об используемых функциях: например, ?which, ?apply ...

0 голосов
/ 19 ноября 2018

Я подозреваю, что вы, скорее всего, имеете prcomp объект, а не фрейм данных, но не имеет значения

exampldf <- data.frame(PC1 = c(0.97, 0.40, 0.85, 0.75),
                       PC2 = c(0.01, 0.20, 0.10, 0.10),
                       PC3 = c(0.01, 0.20, 0.03, 0.10),
                       PC4 = c(0.01, 0.20, 0.02, 0.05))
rownames(exampldf) <- c("WEEK1", "WEEK2", "WEEK3", "WEEK4")
library(matrixStats)
exampldf$PC_N <- 1 + rowSums(rowCumsums(as.matrix(exampldf)) < 0.9)

производит

> exampldf
       PC1  PC2  PC3  PC4 PC_N
WEEK1 0.97 0.01 0.01 0.01    1
WEEK2 0.40 0.20 0.20 0.20    4
WEEK3 0.85 0.10 0.03 0.02    2
WEEK4 0.75 0.10 0.10 0.05    3
0 голосов
/ 19 ноября 2018

Я бы написал функцию, которая возвращает количество элементов вектора, необходимое для сложения не менее 0,9, na.rm = T, а затем применяет его по строкам к соответствующим столбцам df:

get.length <- function(x) {
  ind <- which.max(x)
  sum <- max(x)
  if (sum >= .9) {
    return(1)
  } else {
    while (sum < .9 & length(ind) != length(x)) {
      ind <- c(ind, which.max(x[-ind]))
      sum <- sum(x[ind], na.rm = T)
    }
  }
  if (sum < .9) return(NA) else return(length(ind))
}

Функция ищет максимальное значение вектора и, если оно меньше 0, добавляет следующее наибольшее и повторяется. По достижении 0,9 возвращается количество элементов, необходимое для суммирования не менее 0,9. Если они этого не делают, он возвращает NA.

Примечание. Даже если ваши компьютеры будут стоить меньше, функция работает, даже если элементы не отсортированы в порядке убывания.

Вы можете применить функцию к индексам столбцов вашего фрейма данных df следующим образом:

apply(df[ , col_indices], 1, get.length)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...