Итеративное вычитание по многим столбцам, основанное на условии в R - PullRequest
0 голосов
/ 28 мая 2018

Мои данные содержат статистические данные о результатах футбольного матча с 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

Для каждого уникального "идентификатора матча" я хочу вычесть каждый из проигравших (Outcome == "Loss" ключевых показателей эффективности из команды-победителя (Outcome == "Win"). Мой data.set не являетсявсегда упорядоченный по Loss, Win, Loss, Win, так что завершение этого подряд может быть невозможным.

Я пробовал следующее, используя 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?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Для суммирования данных можно использовать 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)
0 голосов
/ 28 мая 2018

Разница двух логических векторов одинаковой длины.Нам нужно подставить столбцы «Var», где «Outcome» равен "Win", взять 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 в «длинный» формат, получить группу с разницей sum и spread в «широкий» формат

Test %>% 
  gather(key, val, Var1:Var5) %>% 
  group_by(MatchID, key) %>%
  summarise(val = sum(val[Outcome == "Win"]) - sum(val[Outcome == "Loss"])) %>%
  spread(key, val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...