data.frame: условное добавление строк - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть датафрейм punkt_tabelle, содержащий очки, сделанные в игре.Каждая игра имеет 2 или 3 комплекта (3 в MRE).Фрейм данных содержит, как были сделаны точки.У меня также есть результаты в конце набора, который хранится в scores.Я рассчитываю сумму для каждой команды в каждом наборе.(Я сделал это в total_pts).

То, чего я пытаюсь добиться, - это сравнить сумму баллов из таблицы данных (за команду и за сет) с баллами, которые эта команда получила согласно scores.Если scores в этом наборе больше, чем сумма, вычисленная как total, тогда я хочу добавить дополнительную строку в таблицу данных.Эта новая строка должна содержать имя команды, набор и навык для этой новой строки должны быть "Opp. Other Errors" , а значение для Pkt будет разницей между scores и total,Возможно (и имеет место в MRE), что новая строка должна быть добавлена ​​для каждой команды и каждого сета.

Если бы вы повторно запустили вычисление total_pts после были добавлены новые строки, поэтому они будут равны результатам в scores.

Я пробовал варианты приведенного ниже кода в соответствии с этими вопросами и статьями ( R Условная оценка при использовании оператора канала%>%, Вставка новой строки во фрейм данных для каждого идентификатора группы ), но не может найти решение для моей проблемы.

Вот последняя версия моего кода:

library(dplyr)
library (devtools)

punkt_tabelle <- structure(list(Team = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 
                 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
                 1L), .Label = c("Miller/Myer", "Winter/Summer"), class = "factor"), 
                 Skill = structure(c(1L, 1L, 3L, 2L, 2L, 2L, 1L, 1L, 3L, 2L, 
                 2L, 2L, 4L, 4L, 5L, 6L, 6L, 6L, 4L, 4L, 5L, 6L, 6L, 6L), .Label = c("Attack", 
                 "Service", "Block", "Opp. Attack Error", "Opp. Block Error", 
                 "Opp. Serve Error"), class = "factor"), Set = c(2L, 3L, 2L, 
                 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 2L, 1L, 2L, 3L, 
                 1L, 2L, 3L, 1L, 2L, 3L), Pkt = c(2L, 1L, 1L, 0L, 0L, 0L, 
                 3L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 
                 0L, 1L, 0L)), row.names = c(NA, -24L), vars = c("Team", "Skill"
                 ), indices = list(0:1, 2L, 18:19, 20L, 21:23, 3:5, 6:7, 8L, 12:13, 
                 14L, 15:17, 9:11), group_sizes = c(2L, 1L, 2L, 1L, 3L, 3L, 
                 2L, 1L, 2L, 1L, 3L, 3L), biggest_group_size = 3L, labels = structure(list(
                 Team = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
                 2L, 2L), .Label = c("Miller/Myer", "Winter/Summer"), class = "factor"), 
                 Skill = c("Attack", "Block", "Opp. Attack Error", "Opp. Block Error", 
                 "Opp. Serve Error", "Service", "Attack", "Block", "Opp. Attack Error", 
                 "Opp. Block Error", "Opp. Serve Error", "Service")), row.names = c(NA, 
                 -12L), class = "data.frame", vars = c("Team", "Skill")), class = c("grouped_df", 
                  "tbl_df", "tbl", "data.frame"))



score_miller_myer <- c(3,6,3) #total points in sets 1, 2, 3
score_winter_summer <- c(5,4,5)
scores <- c(score_miller_myer, score_winter_summer)

#calculate the sum of the points per team and per set
total_pts <- punkt_tabelle %>% group_by(Team, Set) %>% summarize(total = sum(Pkt))
total_pts

#try to compare with the score and add en entry in the dataframe
punkt_tabelle %>% 
  group_by (Team, Set) %>% 
  mutate(total = sum(Pkt)) %>% 
  {if (total<scores) dplyr::bind_rows(Team=Team, Set=Set, Skill="Opp. Other Error", Pkt=(total-scores))}

punkt_tabelle

Можно ли это как-то так сделать?Или мне нужно использовать цикл и делать это вручную для каждого набора и команды?Пожалуйста, помогите!

РЕДАКТИРОВАТЬ: ожидаемый результат в этом примере будет выглядеть следующим образом:

Team          Skill               Set   Pkt
<fct>         <fct>             <int> <int>
 1 Miller/Myer   Attack                2     2
 2 Miller/Myer   Attack                3     1
 3 Miller/Myer   Block                 2     1
 4 Miller/Myer   Service               1     0
 5 Miller/Myer   Service               2     0
 6 Miller/Myer   Service               3     0
 7 Winter/Summer Attack                1     3
 8 Winter/Summer Attack                2     1
 9 Winter/Summer Block                 3     1
10 Winter/Summer Service               1     0
11 Winter/Summer Service               2     1
12 Winter/Summer Service               3     1
13 Winter/Summer Opp. Attack Error     2     0
14 Winter/Summer Opp. Attack Error     3     0
15 Winter/Summer Opp. Block Error      2     0
16 Winter/Summer Opp. Serve Error      1     0
17 Winter/Summer Opp. Serve Error      2     1
18 Winter/Summer Opp. Serve Error      3     1
19 Miller/Myer   Opp. Attack Error     1     1
20 Miller/Myer   Opp. Attack Error     2     0
21 Miller/Myer   Opp. Block Error      3     0
22 Miller/Myer   Opp. Serve Error      1     0
23 Miller/Myer   Opp. Serve Error      2     1
24 Miller/Myer   Opp. Serve Error      3     0
25 Winter/Summer Opp. Other Error      1     2  #here start the added rows
26 Winter/Summer Opp. Other Error      2     1  
27 Winter/Summer Opp. Other Error      3     2
28 Miller/Myer   Opp. Other Error      1     2
29 Miller/Myer   Opp. Other Error      2     2
30 Miller/Myer   Opp. Other Error      3     2

Дальнейшее объяснение проблемы: команда забивает различными способами.Либо они забивают сами (Атака, Служить, Блокируют), либо их оппонент совершает ошибку (Опп. Ошибка атаки, Опп. Ошибка подачи, Опп. Ошибка блока).Тем не менее, это оставляет некоторую разницу в общем счете, которого они достигают, потому что есть некоторые ошибки противников, которые не указаны.Для этого я хочу добавить строку «Опп. Прочие ошибки» после расчета разницы.

Пример: в строке 26: значение Pkt равно 1, поскольку в total_pts в наборе 2 команда зима / лето имеет3 баллаНо их оценка согласно score_winter_summer в наборе 2 составляет 4 балла.Таким образом, есть разница в 1 балл, которая добавляется в новую строку.

1 Ответ

0 голосов
/ 06 декабря 2018

Вот возможность.

  1. Сначала нам нужно сохранить scores в data.frame, который включает в себя информацию о Team и Set

    df.scores <- data.frame(
        Team = c(rep("Miller/Myer", 3), rep("Winter/Summer", 3)),
        Set = 1:3,
        scores = scores)
    

    Давайте проверим df.scores

    df.scores
    #           Team Set scores
    #1   Miller/Myer   1      3
    #2   Miller/Myer   2      6
    #3   Miller/Myer   3      3
    #4 Winter/Summer   1      5
    #5 Winter/Summer   2      4
    #6 Winter/Summer   3      5
    
  2. Далее мы сделаем левое соединение punk_tabelle с df.scores на Team и Set, вычислимсумма баллов Total = sum(Pkt) по Team и Set;Opp. Other Error определяется как разница между scores и Total.Окончательный ожидаемый результат достигается путем преобразования длинных в широкие в длинные.

    punkt_tabelle %>%
        left_join(df.scores) %>%
        group_by(Team, Set) %>%
        mutate(
            Total = sum(Pkt),
            `Opp. Other Error` = scores - Total) %>%
        spread(Skill, Pkt) %>%
        select(-scores, -Total) %>%
        gather(Skill, Pkt, -Team, -Set)
    #Joining, by = c("Team", "Set")
    ## A tibble: 42 x 4
    ## Groups:   Team, Set [6]
    #   Team            Set Skill              Pkt
    #   <fct>         <int> <chr>            <dbl>
    # 1 Miller/Myer       1 Opp. Other Error     2
    # 2 Miller/Myer       2 Opp. Other Error     2
    # 3 Miller/Myer       3 Opp. Other Error     2
    # 4 Winter/Summer     1 Opp. Other Error     2
    # 5 Winter/Summer     2 Opp. Other Error     1
    # 6 Winter/Summer     3 Opp. Other Error     2
    # 7 Miller/Myer       1 Attack              NA
    # 8 Miller/Myer       2 Attack               2
    # 9 Miller/Myer       3 Attack               1
    #10 Winter/Summer     1 Attack               3
    ## ... with 32 more rows
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...