总和通过与同时省略从r之和data.table值的多个逻辑条件组(Sum by group with

2019-10-20 19:40发布

我有麻烦找出如何总结排在data.table而省略的过程中某一组的值。

比方说,我有一个data.table以下形式:

library(data.table)
dt <- data.table(year = c(2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003), 
               name = c("Tom", "Tom", "Tom", "Tom", "Fred", "Fred", "Fred", "Fred", "Gill", "Gill", "Gill", "Gill", "Ann", "Ann", "Ann", "Ann"),
               g1 = c(1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1),
               g2 = c(1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1),
               g3 = c(1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1),
               g4 = c(0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1))

setkey(dt, name, year)

其中g1 - g4是游戏中的玩家指示变量name参加了一次year

我想要做的是计算球员每场比赛的数量NPg1 - NPg4 ,其中两个选手参加了焦点比赛,但前提是他们还互相在另一场比赛在同一年发挥,这总和应排除对他们来说,正在计算它的球员。

我亲近使用此代码修改如何在R中一个载体会逐渐增加值例如,对于NPg1

dtg1 <- dt[,.SD[(g1==1) & (g2==1 | g3==1 | g4==1)][, NPg1:= sum(g1)], by=year]

该子集dt我的条件和创建总和,但是,和包括焦点球员。 例如NPg1year==2000是1汤,但它应该是0,因为尽管他在出场g1他没有在那年另一场比赛发挥其他玩家。 一旦我得到的和正确的,然后我就可以做到这一点的每场比赛,结果合并回一个data.table 。 主要的问题是,怎样才能得到这些条件正确的总和。

对于结果NPg1应该是这样的

dtg1$NPg1result <- c(0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3)

任何想法将不胜感激。

@ Mike.Gahan的评论后:

这是子结果为g1 ,也许这不会成为很清楚的形式我的职务。 一旦我有一个正确的,我可以很容易地加入它回满data.table使用:

library(plyr)
dt <- join(dt, dtg1)

或其他合并/ join操作,但由于我的问题是关注的主要子结果,我不想打扰大家一起休息。

编辑后@里卡多Saportas解决方案

所有的游戏的完整期望的结果如下所示:

dtresult <- data.table(year = c(2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003, 2000, 2001, 2002, 2003), 
                   name = c("Ann", "Ann", "Ann", "Ann", "Fred", "Fred", "Fred", "Fred", "Gill", "Gill", "Gill", "Gill", "Tom", "Tom", "Tom", "Tom"), 
                   NPg1 = c(0, 1, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 1, 3, 3), 
                   NPg2 = c(0, 0, 2, 3, 0, 0, 2, 3, 1, 0, 0, 3, 1, 0, 2, 3), 
                   NPg3 = c(0, 0, 3, 2, 0, 2, 3, 0, 1, 2, 3, 2, 1, 2, 3, 2), 
                   NPg4 = c(0, 0, 2, 2, 0, 1, 0, 0, 0, 1, 2, 2, 0, 0, 2, 2))

Answer 1:

一种方法是做对笛卡尔参加year-g1-g2-..-gn组合。

然后在新表中,可以“忽略行” [见注在底部]没有资格-即玩家在玩自己过不去,和那些球员组合只打了一场比赛。

setkeyv(dt, c("year", games))
dt.merged <- merge(dt, dt, all=TRUE, allow.cartesian=TRUE, suffixes=c("", ".y"))
## ignore players playing against themselves
dt.merged[name != name.y, (games) := 0 ]
## ignore player combinations that only shared one game
dt.merged[ (rowSums(dt.merged[, games, with=FALSE]) <= 1) , (games) := 0 ]
## now just sum itup
results <- dt.merged[, lapply(.SD, sum), keyby=list(year, name), .SDcols=games]
## clean up the names
setnames(results, games, paste0("NP", games))

这将产生

results

    year name g1 g2 g3 g4
 1: 2000  Ann  0  0  0  0
 2: 2000 Fred  0  0  0  0
 3: 2000 Gill  0  1  1  1
 4: 2000  Tom  1  1  1  0
 5: 2001  Ann  1  1  0  0
 6: 2001 Fred  0  0  1  1
 7: 2001 Gill  0  0  1  1
 8: 2001  Tom  1  0  1  0
 9: 2002  Ann  1  1  1  1
10: 2002 Fred  1  1  1  0
11: 2002 Gill  1  0  1  1
12: 2002  Tom  1  1  1  1
13: 2003  Ann  1  1  1  1
14: 2003 Fred  1  1  0  0
15: 2003 Gill  1  1  1  1
16: 2003  Tom  1  1  1  1

请注意,你有两个选择,“忽略行”

如果你想保持“0”数全年播放器,然后用

dt.merged[ <filter>,  (games) := 0 ]

如果你不喜欢的“0”数了一年的球员,然后用

dt.merged <- dt.merged[ ! <filter> ]


文章来源: Sum by group with multiple logical conditions while omitting values from sum R data.table