Создание последовательного рейтинга на основе предыдущих рейтингов - PullRequest
4 голосов
/ 16 апреля 2020

У меня проблема с последовательным обновлением рейтингов, и независимо от того, как я пытаюсь найти решение - или сам придумываю его, - у меня не получается.

Я пытаюсь проанализировать результаты эксперимента последовательного выбор, в котором участники должны были найти наилучший вариант (вариант с наивысшим рейтингом). Они были представлены с оценкой в ​​каждом испытании.

У меня есть ID , заказ и рейтинг переменная для каждого выбора. ID - участник, рейтинг показывает, насколько хорош вариант (чем выше рейтинг, тем лучше), а order - номер испытания (в этом примере было 4 испытания)

ID       rating        order
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4

Я хотел бы создать новую переменную под названием «current_rank», которая в основном является рейтингом рейтинга текущего выбора. Эта переменная всегда должна учитывать все предыдущие испытания и рейтинги, поэтому, например, для участника с ID"1" это будет:

Испытание 1: рейтинг = 4, что означает, что это лучший рейтинг, current_rank = 1

Trial 2: rating = 3, что означает, что это второй лучший рейтинг, current_rank = 2

Пробная версия 3: рейтинг = 5, что означает, что это лучший рейтинг на данный момент, что делает его новым номером 1, поэтому current_rank = 1

Пробная версия 4: рейтинг = 2, что означает, что это далеко не самое лучшее, current_rank = 4

Если бы я мог сделать это со всеми участниками и всеми вариантами, моя база данных должна выглядеть так:

ID       rating        order        current_rank
1        4             1            1
1        3             2            2
1        5             3            1
1        2             4            4
2        3             1            1
2        5             2            1
2        2             3            3
2        1             4            4

Я мог бы успешно создать общую переменную ранжирования, такую ​​как:

db %>%
  arrange(ID, order) %>%
  group_by(ID) %>%
  mutate(ovr_rank = min_rank(desc(rating)))

Но моя цель - создать переменную, которая является чем-то вроде последовательного ранжирования. Это позволило бы увидеть, какое мнение участник мог сформировать относительно текущего рейтинга на основе предыдущих рейтингов, не зная, какими могут быть будущие рейтинги. Я пытался создать циклы или использовать функции применения, но пока не смог найти решение.

Любые идеи приветствуются!

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Используйте бегунок , чтобы применить любую функцию R в накопительном окне (или скользящем окне). Ниже я использовал runner, который выставляет рейтинг и применяет функцию ранга к «доступным» данным на данный момент (кумулятивный ранг). Раскомментируйте print, чтобы показать, что попадает в function(x).

library(dplyr)
library(runner)

data %>%
  arrange(ID, order) %>%
  group_by(ID) %>%
  mutate(
    current_rank = runner(
      x = rating,
      f = function(x) {
        # print(x)
        rank_available_at_the_moment <- rank(-x, ties.method = "last")
        tail(rank_available_at_the_moment, 1)
      }
    )
  )


# # A tibble: 8 x 4
# # Groups:   ID [2]
#       ID rating order current_rank
#     <int>  <int> <int>        <int>
# 1     1      4     1            1
# 2     1      3     2            2
# 3     1      5     3            1
# 4     1      2     4            4
# 5     2      3     1            1
# 6     2      5     2            1
# 7     2      2     3            3
# 8     2      1     4            4

data

data <- read.table(text = "ID       rating        order
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4", header = TRUE)
1 голос
/ 17 апреля 2020

Здесь есть 2 варианта использования data.table:

1) неэкви-объединение, чтобы найти все испытания до и включая текущее испытание, оценить рейтинг и извлечь текущий рейтинг:

DT[, cr := .SD[.SD, on=.(ID, trial<=trial), by=.EACHI, order(order(-rating))[.N]]$V1]

2) non-equi join, чтобы найти число оценок, превышающее текущий рейтинг в испытаниях перед текущим испытанием:

DT[, cr2 := DT[DT, on=.(ID, trial<=trial, rating>rating), by=.EACHI, .N + 1L]$V1]

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

вывод:

   ID rating trial cr cr2
1:  1      4     1  1   1
2:  1      3     2  2   2
3:  1      5     3  1   1
4:  1      2     4  4   4
5:  2      3     1  1   1
6:  2      5     2  1   1
7:  2      2     3  3   3
8:  2      1     4  4   4

данные:

library(data.table)
DT <- fread("ID       rating        trial
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4")
1 голос
/ 16 апреля 2020

Этот фрагмент кода будет работать:

df <- tibble(
  ID = c(1,1,1,1,2,2,2,2),
  rating = c(4,3,5,2,3,5,2,1),
  rank = c(1,0,0,0,0,0,0,0)
)

for(i in 2:nrow(df)){
  if(df$ID[i] != df$ID[i-1]){
    df$rank[i] <- 1
  } else {
    df$rank[i] <- which(sort(df[1:i,]$rating[which(df$ID == df$ID[i])], decreasing = TRUE) == df$rating[i])
  }
}

Объяснение:

Обратите внимание, что я предполагаю, что ваш фрейм данных уже упорядочен на основе идентификатора и порядка. В моем df столбце order нет, но это в основном для простоты (и это не обязательно необходимо в моем решении, опять же, при условии, что строки уже упорядочены по ID и порядку).

for l oop просто смотрит, отличается ли идентификатор этой строки от строки выше, он автоматически получает ранг 1. В противном случае он просматривает подмножество df из строки 1 в строку i, подмножества. снова по аналогичному идентификатору сортирует рейтинги в этом подмножестве (включая наш текущий рассматриваемый рейтинг) в порядке убывания и занимает позицию нашего текущего запрашиваемого рейтинга, который будет назначен в качестве значения ранга.

Я надеюсь, что это ответы ваш вопрос и дает вам понимание.

...