【问题标题】:Iterative subtraction, over many columns, based on condition within R基于 R 中的条件,在多列上进行迭代减法
【发布时间】:2018-05-28 06:04:19
【问题描述】:

我的数据包含关于足球比赛结果的统计数据,包括 12806 次观察(比赛结果)和 34 个关键绩效指标。

我的 data.frame 的一个(小)示例如下:

head(Test)
  MatchID Outcome Var1 Var2 Var3 Var4 Var5
1      30    Loss    0   10    0   10    0
2      30     Win    6   13    6   13    6
3      31    Loss    8   12    3    6    3
4      31     Win   29   40    9   19    3
5      32    Loss    7   26    7   26    6
6      32     Win   11   20   11   20    9

对于每个唯一的“匹配 ID”,我希望从获胜 (Outcome=="Win") 团队中扣除每个失败的 (Outcome=="Loss" 关键绩效指标。我的 data.set 并不总是由输,赢,输,赢所以连续完成。明智的方式可能是不可能的。

我使用 dplyr 尝试了以下操作:

 Differences <- Test %>% 
   group_by(MatchID) %>% 
   summarise_at( .vars = names(.)[3:7], ((Outcome == "Win") - (Outcome == "Loss")))

但担心我使用了错误的方法,因为我收到以下错误:Error in inherits(x, "fun_list") : object 'Outcome' not found

我的预期结果是:

head(AnticipatedOutcome)
  MatchID Var1 Var2 Var3 Var4 Var5
1      30  6    3    6    3    6
3      31 21   28    6   13    0
5      32  4   -6    4   -6    3

请问使用 dplyr 可以实现吗?

【问题讨论】:

  • @akrun 道歉,这是更新以反映我的例子。
  • 感谢您的更新。你能检查更新的summarised 输出吗

标签: r dplyr


【解决方案1】:

两个逻辑向量的差长度相同。我们需要对“Outcome”为"Win"的“Var”列进行子集化,取其中的sum并从“Outcome”为"Loss"的列中减去它

library(tidyverse)
Test %>%
    group_by(MatchID) %>%
    summarise_at(vars(starts_with('Var')),
              funs(sum(.[Outcome == "Win"]) - sum(.[Outcome == "Loss"])))
# A tibble: 3 x 6
#  MatchID  Var1  Var2  Var3  Var4  Var5
#    <int> <int> <int> <int> <int> <int>
#1      30     6     3     6     3     6
#2      31    21    28     6    13     0
#3      32     4    -6     4    -6     3

或者另一种选择是将gather 转换为“长”格式,通过sumspread 的差异将组设置为“宽”格式

Test %>% 
  gather(key, val, Var1:Var5) %>% 
  group_by(MatchID, key) %>%
  summarise(val = sum(val[Outcome == "Win"]) - sum(val[Outcome == "Loss"])) %>%
  spread(key, val)

【讨论】:

  • 感谢您在我添加更新时的选择和耐心等待!
【解决方案2】:

可以使用data.table.SDcols 参数来汇总数据。正如@akrun 在他的解决方案中提到的那样,每场比赛的“输”的sum 将从“赢”的sum 中减去。

library(data.table)

setDT(df)

df[,lapply(.SD,function(x)sum(x[Outcome=="Win"]) - sum(x[Outcome=="Loss"])), 
   .SDcols = Var1:Var5,by=MatchID]

#    MatchID Var1 Var2 Var3 Var4 Var5
# 1:      30    6    3    6    3    6
# 2:      31   21   28    6   13    0
# 3:      32    4   -6    4   -6    3

注意:只是为了探索不同的想法,但即使base-R也可以达到相同的结果:

cbind(unique(df[1]), df[order(df$MatchID),][df$Outcome == "Win",3:7] - 
        df[order(df$MatchID),][df$Outcome == "Loss",3:7])

#   MatchID Var1 Var2 Var3 Var4 Var5
# 1      30    6    3    6    3    6
# 3      31   21   28    6   13    0
# 5      32    4   -6    4   -6    3

数据:

df <- read.table(text =
"MatchID Outcome Var1 Var2 Var3 Var4 Var5
1      30    Loss    0   10    0   10    0
2      30     Win    6   13    6   13    6
3      31    Loss    8   12    3    6    3
4      31     Win   29   40    9   19    3
5      32    Loss    7   26    7   26    6
6      32     Win   11   20   11   20    9",
header =TRUE, stringsAsFactors = FALSE)

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    相关资源
    最近更新 更多