2016-09-24 50 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: ... 

因此,有几个队几名球员,回答几个问题。总是有两轮比赛。

我试图通过对团队和问题进行分组,从数据中计算出介质和协议系数(请参阅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 

是否有人知道这是可能的吗?我找不到解决方案。我可以独立解决中位数和协议系数,但不能合并?

每一个提示是值得欢迎的。非常感谢你。

UPDATE:
该协议函数返回之间-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的实现。我不得不添加另一个排序步骤,以便合并正确的数据。框架:

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'包Vignette,只是告诉我们你想用什么函数来计算协议。 – eipi10

回答

1

以下是三种方法:基础R aggregatedplyrdata.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)))) 

最后,重塑宽格式。这需要首先“熔化”数据以将MedianAgreement列堆叠到一个列中,然后转换为宽格式。我们还以第二行代码为“回合”添加到每个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