как повторить ту же функцию по строкам в матрице - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь написать цикл, который определяет, какая ячейка имеет наибольшее значение, и выбрать эту ячейку в результате с высокой средней или низкой строкой. Вот данные для опробования.

data <- matrix(c(0.3000003,0.3299896,0.3700101,
                 0.3299896,0.3700101,0.3000003,
                 0.3700101,0.3000003,0.3299896,
                 0.3000003,0.3299896,0.3700101,
                 0.3299896,0.3700101,0.3000003,
                 0.3700101,0.3000003,0.3299896),6,3)
colnames(data) <- c("Low","Medium","High")
rownames(data) <- paste("case",1:6)

> data
             Low    Medium      High
case 1 0.3000003 0.3700101 0.3299896
case 2 0.3299896 0.3000003 0.3700101
case 3 0.3700101 0.3299896 0.3000003
case 4 0.3299896 0.3000003 0.3700101
case 5 0.3700101 0.3299896 0.3000003
case 6 0.3000003 0.3700101 0.3299896

Я использую эту функцию, но похоже, что она вычисляет только первую строку.

assign.levels <- function(data) {

  for (i in nrow(data)) {

    scored.thetas.1 <- names(which.max(data[i,1:3])) ## I wrote 1:3 here becasue I have multiple coloumns in the original dataset.
    return(scored.thetas.1)

  }
}


> assign.levels(data)
[1] "Medium"

Есть мысли?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Это должно быть быстро

colnames(data)[max.col(data)]
#[1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

Вот небольшой тест.

n <- 1e6
set.seed(1)
data <- matrix(runif(n * 3), ncol = 3)
colnames(data) <- c("Low","Medium","High")

library(microbenchmark)

benchmark <- microbenchmark(
  OP = assign.levels(data), # as defined in Julius's answer
  Julius = colnames(data)[apply(data, 1, which.max)],
  markus = colnames(data)[max.col(data)], times = 20
)

autoplot(benchmark)

enter image description here

0 голосов
/ 30 октября 2018

Вот векторизованное решение, которое вы можете предпочесть:

colnames(data)[apply(data, 1, which.max)]
# [1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

Это краткая версия вашей попытки: apply функция which.max для каждой строки (размерность 1) data и получение соответствующего имени столбца.

С точки зрения вашей попытки, вот исправленная версия:

assign.levels <- function(data) {
  scored.thetas.1 <- rep(NA, nrow(data))
  for (i in 1:nrow(data))
    scored.thetas.1[i] <- names(which.max(data[i, ]))
  scored.thetas.1
}
assign.levels(data)
# [1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

Несколько замечаний по поводу вашей попытки: 1) вы итерировали с i in nrow(data), тогда как nrow(data) - это просто число. Так что в основном вы смотрели только на последний ряд; 2) вы продолжали переопределять одну и ту же переменную scored.thetas.1 в на каждой итерации (в этом случае была только одна итерация, но тенденция была плохой); 3) цикл не является функцией, вам не нужно ничего возвращать из него, и вместо этого вы, скорее всего, захотите где-то сохранить вновь полученные значения.

Для сравнения, обратите внимание, что сначала я определяю пустой вектор scored.thetas.1 длины nrow(data). Затем я перебираю все строки (1:nrow(data)) и сохраняю значение для каждой строки / итерации в scored.thetas.1[i].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...