【问题标题】:Multilevel summarize with dplyr in R在 R 中使用 dplyr 进行多级汇总
【发布时间】:2016-06-03 11:40:06
【问题描述】:

我有一组这样的数据

project,file,line,mutant,killstatus,commitid,isbug
p1,f1,100,NMC,killed,abc123,yes
p1,f1,100,VMC,alive,abc123,yes
p1,f1,200,NVM,alive,ab12de,no
p1,f1,200,NVM,alive,abcde1,yes
p1,f1,200,NVM,alive,abcde2,yes

我想按项目、文件、行进行分组并总结为

project,file,line,total.mutants,killed.mutants,total.commits,bugfix.commits
p1,f1,100,2,1,1,1
p1,f1,200,1,0,3,2

即对于每个project,file,line组合,total.mutants的长度是(mutant,killstatus)的唯一计数,killed.mutants是前一对killed的计数。同样,total.commits(commitid,isbug) 的唯一计数,bugfix.commits 是前一对中 yes 的计数。

澄清: 对于p1,f1,100,有两个独特的突变体,killstatus 对(NMC,killed),(VMC,alive),其中一个被杀死。因此2,1 总计,被杀 对于p1,f1,200,只有一个独特的突变体,killstatus 对(NVM,alive) 是活着的。因此,1,0 总计被杀

对于p1,f1,100,有一个唯一的commitid,是错误对(abc123,yes),这是一个错误。因此1,1 总计,错误修复 对于p1,f1,200,有三个唯一的commitid,isbug 对(ab12de,no),(abcde1,yes),(abcde2,yes),其中两个是bug。因此3,2 总计,错误修复

我可以使用 dplyr 一口气总结吗?我设法做到了第一个部分喜欢

data %>% group_by(project,file,line) %>% summarize(
   total.mutants = length(killstatus),
   killed.mutants = sum(ifelse(killstatus == 'alive', F, T))
)

但我不知道如何做独特的部分和第二部分。

【问题讨论】:

  • 应该有 1 个错误修复提交,第一行总共提交 1 个 (100),第二行总共 3 个提交中有 2 个错误修复提交 (200)

标签: r dplyr


【解决方案1】:

我们可以试试

library(dplyr)
library(data.table)
df1 %>%
 group_by(project,file,line) %>% 
  transmute(temp1 = paste(mutant, killstatus),

          total.mutants= uniqueN(temp1),
          killed.mutants= uniqueN(paste(mutant[killstatus=='killed'],
                            killstatus[killstatus=='killed'])),
         temp2=paste(commitid, isbug), 
         total.commits= uniqueN(temp2), 
         bug.commits= uniqueN(paste(commitid[isbug=="yes"], 
                            isbug[isbug=="yes"])) ) %>%
         distinct(., project, file, line) %>%
         select(-temp1, -temp2) 
#     project  file  line total.mutants killed.mutants total.commits bug.commits
#    (chr) (chr) (int)         (int)          (int)         (int)       (int)
#1      p1    f1   100             2              1             1           1
#2      p1    f1   200             1              0             3           2

或者使用unite 来自tidyr 的稍微更紧凑的版本

library(tidyr)
df1 %>% 
    unite(temp1,mutant, killstatus) %>%
    unite(temp2, commitid, isbug) %>%
    group_by(project, file, line) %>% 
    summarise(total.mutants= n_distinct(temp1), 
               killed.mutants= uniqueN(temp1[grepl("killed", temp1)]),
               total.commits= n_distinct(temp2),
               bug.commits= uniqueN(temp2[grepl("yes", temp2)]))
#     project  file  line total.mutants killed.mutants total.commits bug.commits
#     (chr) (chr) (int)         (int)          (int)         (int)       (int)
#1      p1    f1   100             2              1             1           1
#2      p1    f1   200             1              0             3           2

【讨论】:

  • killed.mutants 应该在 total.mutants 之外,bugfix.commits 应该在 total.commits 之外(即,它们在唯一对中进行搜索)
  • 我已经在问题中澄清了。现在有意义吗?
  • 假设我添加了p1,f1,100,NMC,killed,bbb123,yesp1:f1:100 的额外行,我总共有 2 个突变体用于该行(应用您的代码是正确的),但我仍然只会杀死 1 个突变体,在您的代码中显示为 2
  • @rahul 你能试试第二段代码吗?我认为在第一个代码块中,我们必须使用与isbug=='yes'中相同的逻辑
  • @rahul 其他选项也应该可以。我们需要创建两个temp 列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 2018-08-03
相关资源
最近更新 更多