Как создать новый вектор на основе определенного значения в другом векторе?

#r #data-manipulation

#r #манипулирование данными

Вопрос:

У меня есть следующий код:

 set.seed(6)
round<-rep(1:6,2)
players<-rep(1:2, c(6,6))
decs<-sample(1:3,12,replace=TRUE)
game<-rep(rep(1:2,c(3,3)),2)
my_decs<-(c(0,0,0,0,0,4,0,0,0,0,0,9))
gamematrix<-cbind(players,game,round,decs,my_decs)

        players game round decs my_decs
 [1,]       1    1     1    2       0
 [2,]       1    1     2    3       0
 [3,]       1    1     3    1       0
 [4,]       1    2     4    2       0
 [5,]       1    2     5    3       0
 [6,]       1    2     6    3       4
 [7,]       2    1     1    3       0
 [8,]       2    1     2    3       0
 [9,]       2    1     3    2       0
[10,]       2    2     4    1       0
[11,]       2    2     5    2       0
[12,]       2    2     6    3       9
  

Теперь я хочу создать новую переменную, основанную для каждого участника на значении «my decs» в последнем раунде, которое всегда равно 6.
Я хочу, чтобы новая переменная была значением «my_decs» в последнем раунде: поэтому конечный результат должен быть:

          players game round decs my_decs new_var
 [1,]       1    1     1    2       0       4
 [2,]       1    1     2    3       0       4
 [3,]       1    1     3    1       0       4
 [4,]       1    2     4    2       0       4
 [5,]       1    2     5    3       0       4
 [6,]       1    2     6    3       4       4
 [7,]       2    1     1    3       0       9
 [8,]       2    1     2    3       0       9
 [9,]       2    1     3    2       0       9
[10,]       2    2     4    1       0       9
[11,]       2    2     5    2       0       9
[12,]       2    2     6    3       9       9
  

Как я могу это сделать?

Комментарии:

1. Возможно, поспешно gamematrix$new_var <- gamematrix$my_decs[ 6 6*((1:12 - 1) %/% 6) ] . (Я должен добавить, что это грубо и действительно может стать жертвой всевозможных аномалий данных. Было бы гораздо лучше сделать что-то более реактивное, как в «group by … и найдите последнее значение».)

2. Извлеките значения my_decs откуда round == 6 и повторите эти значения шесть раз: rep(gamematrix[, "my_decs"][gamematrix[, "round"] == 6], each = 6) (потому что всегда будет шесть раундов, если я вас правильно понял).

Ответ №1:

Использование tidyverse пакета:

 library(tidyverse)
gamematrix %>% 
  as.data.frame() %>% 
  group_by(players) %>% 
  mutate(new_var = tail(my_decs, 1))
  

Комментарии:

1. В dplyr также last(my_decs) есть

Ответ №2:

Рассмотрите возможность использования data.table:

 library(data.table)
gamematrix <- as.data.table(gamematrix)
gamematrix[,new_var:=max(my_decs),by=players]
    players game round decs my_decs new_var
 1:       1    1     1    2       0       4
 2:       1    1     2    3       0       4
 3:       1    1     3    1       0       4
 4:       1    2     4    2       0       4
 5:       1    2     5    3       0       4
 6:       1    2     6    3       4       4
 7:       2    1     1    3       0       9
 8:       2    1     2    3       0       9
 9:       2    1     3    2       0       9
10:       2    2     4    1       0       9
11:       2    2     5    2       0       9
12:       2    2     6    3       9       9
  

Комментарии:

1. Или gamematrix[, new_var := my_decs[.N], by=players] , если это строго должно быть последнее значение, независимо от того, является ли оно max или нет.