2016-09-24 3 views
1

У меня есть следующие структуры данных:R: как создать медиану и функцию соглашения для нескольких групп

 Player Team Round Question Answer 
1:  2 1  1  1  1 
2:  5 1  1  1  1 
3:  8 1  1  1  1 
4:  9 1  1  1  1 
5:  10 1  1  1  1 
6:  2 1  1  2  4 
7:  5 1  1  2  5 
8:  8 1  1  2  5 
9:  9 1  1  2  5 
10:  10 1  1  2  5 
11:  2 1  1  4  4 
12:  5 1  1  4  3 
13:  8 1  1  4  4 
14:  9 1  1  4  2 
15:  10 1  1  4  4 
16: ... 

Так есть несколько игроков из несколько команды, отвечая на несколько вопросов. Всегда есть 2 раунда игр.

То, что я пытаюсь вычислить, - это средний и коэффициент согласия (см. agrmt package) по данным , объединив команду и вопрос.

Результат должен выглядеть следующим образом:

 Team Question Median_R1 Agrmt_R1 Median_R2 Agrmt_R2 
1:  1  1   1  1   1  1 
2:  1  2   2  0.83   1  1 
3:  ... 
4:  5  10   4  1   4  1 

знает кто, если это возможно? Я не мог найти решение для этого. Я могу решить медианный и согласующий коэффициент отдельно, но не комбинированный?

Каждый намек приветствуется. Большое спасибо.

ОБНОВЛЕНИЕ:
Функция соглашение возвращает коэффициент между -1 и 1. Значения представляют.

  • 1 представляет полное соглашение (например, если каждый игрок отвечает 5).
  • 0 будет, если у каждого игрока есть другой ответ.
  • -1 было бы, если разногласие существует (некоторые игроки говорят, ответ 1 и другие говорят, 5)

enter image description here

По сравнению с медианой, функции соглашения переводит вектор вектора частоты.

Например, мы имеем следующие ответы

 Player Team Round Question Answer 
6:  2 1  1  2  4 
7:  5 1  1  2  5 
8:  8 1  1  2  5 
9:  9 1  1  2  5 
10:  10 1  1  2  5 

Функциональные входы будут выглядеть следующим образом:
Медиана ввода: 4,5,5,5,5 -> Результат: 5
вход Соглашение: 0,0,0,1,4 -> Результат: 0,9

ОБНОВЛЕНИЕ 2: решаемые

Расчет соглашение может быть сделано с помощью следующего кода:

agreement(table(factor(x, levels=1:5))) 

Окончательный вариант основан на реализации @sandipan. Я должен добавить еще один шаг сортировки, чтобы объединить правильные data.frames:

library(agrmt) 
df1 <- unique(df[c('Party', 'Question')]) 
for (df.R in split(df, df$Round)) { 
    round <- unique(df.R$Round) 
    # get the data.frame of the current Round. 
    df2 <- as.data.frame(as.list(aggregate(Answer ~ Party + Question + Round, 
      df.R, FUN = function(x) c(Median = median(x), Agrmt = agreement(table(factor(x, levels=1:5))))))) 
    # sort it and take only the columns of median and agreement 
    df3 <- df2[with(df2, order(Party, Question)),][4:5] 
    names(df3) <- c(paste('Median_R', round, sep=''), paste('Agrmt_R', round, sep='')) 
     df1 <- cbind.data.frame(df1, df3) 
} 

df1 

Спасибо всем за помощь.

+1

Вместо того, чтобы просить нас прочитать виньетку 'agrmt', просто сообщите нам, какую функцию вы хотите использовать для расчета соглашения. – eipi10

ответ

1

Вот три подхода: основание R aggregate, dplyr и data.table.

С базой R aggregate:

library(agrmt) 

aggregate(Answer ~ Team + Round + Question, data=dat, 
      FUN = function(x) { 
      c(Median=median(x), 
       Agreement=agreement(table(factor(x, levels=1:5)))) 
      }) 
Team Round Question Answer.Median Answer.Agreement 
1 1  1  1   1.0    1.0 
2 1  1  2   5.0    0.9 
3 1  1  4   4.0    0.7 

С dplyr:

library(dplyr) 

dat.summary = dat %>% group_by(Team, Round, Question) %>% 
    summarise(Median=median(Answer), 
      Agreement=agreement(table(factor(Answer, levels=1:5)))) 
Team Round Question Median Agreement 
1  1  1  1  1  1.0 
2  1  1  2  5  0.9 
3  1  1  4  4  0.7 

С data.table:

library(data.table) 

dat.summary = setDT(dat)[, list(Median=median(Answer), 
           Agreement=agreement(table(factor(Answer, levels=1:5)))), 
         by=list(Team, Round, Question)] 
Team Round Question Median Agreement 
1: 1  1  1  1  1.0 
2: 1  1  2  5  0.9 
3: 1  1  4  4  0.7 

Для того, чтобы получить "широкий" кадр данных в качестве конечного выходного сигнала:

В примерах выше, я «Выходной файл вышел в« длинном »формате. Если вы хотите переформатировать в «широкий» формат, чтобы каждый Round получил свой собственный набор столбцов, вы можете сделать следующее:

Сначала добавим второй раунд к образцу данных, уложив еще одну копию образца данные:

library(dplyr) 
library(reshape2) 
library(agrmt) 

dat = bind_rows(dat, dat %>% mutate(Round=2)) 

Теперь рассчитать медиану и согласие с тем же кодом, который мы использовали раньше в dplyr например:

dat.summary = dat %>% 
    group_by(Team, Round, Question) %>% 
    summarise(Median=median(Answer), 
      Agreement=agreement(table(factor(Answer, levels=1:5)))) 

Наконец, перекроить в широком формате. Для этого необходимо сначала «расплавить» данные, чтобы стекировать столбцы Median и Agreement в один столбец, а затем лить в широкий формат. Мы также включаем вторую строку кода, чтобы добавить «Round» для каждого Round так, что мы получаем имена столбцов, которые мы хотим в широком кадре данных:

dat.summary = dat.summary %>% 
    mutate(Round = paste0("Round", Round)) %>% 
    melt(id.var=c("Team","Question","Round")) %>% 
    dcast(Team + Question ~ variable + Round, value.var="value") 
Team Question Median_Round1 Median_Round2 Agreement_Round1 Agreement_Round2 
1 1  1    1    1    1.0    1.0 
2 1  2    5    5    0.9    0.9 
3 1  4    4    4    0.7    0.7 
1

Я думаю, что вы хотите что-то следующим образом, правильно?

df 
    Player Team Round Question Answer 
1:  2 1  1  1  1 
2:  5 1  1  1  1 
3:  8 1  1  1  1 
4:  9 1  1  1  1 
5:  10 1  1  1  1 
6:  2 1  1  2  4 
7:  5 1  1  2  5 
8:  8 1  1  2  5 
9:  9 1  1  2  5 
10:  10 1  1  2  5 
11:  2 1  1  4  4 
12:  5 1  1  4  3 
13:  8 1  1  4  4 
14:  9 1  1  4  2 
15:  10 1  1  4  4 
16:  2 1  2  1  2 
17:  5 1  2  1  3 
18:  8 1  2  1  4 
19:  2 1  2  2  5 
20:  5 1  2  2  3 
21:  8 1  2  2  1 
22:  2 1  2  4  6 
23:  5 1  2  4  1 
24:  8 1  2  4  5 

library(agrmt) 
df1 <- unique(df[c('Team', 'Question')]) 
for (df.R in split(df, df$Round)) { 
    round <- unique(df.R$Round) 
    df2 <- as.data.frame(as.list(aggregate(Answer ~ Team + Question + Round, 
      df.R, FUN = function(x) c(Median = median(x), Agrmt = agreement(x)))))[4:5] 
    names(df2) <- c(paste('Median_R', round, sep=''), paste('Agrmt_R', round, sep='')) 
    df1 <- cbind.data.frame(df1, df2) 
} 

df1 
    Team Question Median_R1 Agrmt_R1 Median_R2 Agrmt_R2 
1:  1  1   1 0.00000000   3 0.2222222 
6:  1  2   5 0.04166667   3 0.4444444 
11: 1  4   4 -0.05882353   5 -0.5833333 
+0

Выглядит очень хорошо. Единственная проблема заключается в том, что функции соглашения, похоже, не работают должным образом. Я предполагаю, что проблема в том, что требуется вектор частоты (см. Обновленное описание). – tstuber

Смежные вопросы