2016-01-01 6 views
4

Скажем, у меня есть следующие исторические результаты лиги:Как запаздывать по целочисленной переменной с использованием R?

Season <- c(1,1,2,2,3,3,4,4,5,5) 
Team <- c("Diverpool","Deverton","Diverpool","Deverton","Diverpool","Deverton","Diverpool","Deverton","Diverpool","Deverton") 
End.Rank <- c(8,17,4,15,3,6,4,16,3,17) 
PLRank <- cbind(Season,Team,End.Rank) 

Я хочу (эффективно) создать один год отставал переменную для каждой команды на основе двух критериев:

  1. лаг End.Rank по Season (т.е. т-1 с Season в качестве временной переменной)
  2. отдельной командой (Deverton-х отставал End.Rank против Diverpool-х отставал End.Rank)

По сути, я хотел бы выход быть следующим:

l.End.Rank <- c(NA,NA,8,17,4,15,3,6,4,16) 

Пробовал lag(), и потерял при попытке сделать это в for() петлю на данный момент.

ответ

2

Вы можете попробовать один из следующих ...

Обратите внимание, что я использовал data.frame вместо того, matrix вы получаете с cbind:

PLRank <- data.frame(Season, Team, End.Rank) 

С "data.table":

library(data.table) 
setDT(PLRank)[, l.End.Rank := shift(End.Rank), by = .(Team)][] 
#  Season  Team End.Rank l.End.Rank 
# 1:  1 Diverpool  8   NA 
# 2:  1 Deverton  17   NA 
# 3:  2 Diverpool  4   8 
# 4:  2 Deverton  15   17 
# 5:  3 Diverpool  3   4 
# 6:  3 Deverton  6   15 
# 7:  4 Diverpool  4   3 
# 8:  4 Deverton  16   6 
# 9:  5 Diverpool  3   4 
# 10:  5 Deverton  17   16 

Или, с "dplyr":

library(dplyr) 
PLRank %>% 
    group_by(Team) %>% 
    mutate(l.End.Rank = lag(End.Rank)) 
# Source: local data frame [10 x 4] 
# Groups: Team [2] 
# 
# Season  Team End.Rank l.End.Rank 
#  (dbl) (fctr) (dbl)  (dbl) 
# 1  1 Diverpool  8   NA 
# 2  1 Deverton  17   NA 
# 3  2 Diverpool  4   8 
# 4  2 Deverton  15   17 
# 5  3 Diverpool  3   4 
# 6  3 Deverton  6   15 
# 7  4 Diverpool  4   3 
# 8  4 Deverton  16   6 
# 9  5 Diverpool  3   4 
# 10  5 Deverton  17   16 

Update

я честно совершенно неправильно, что вы хотели это сгруппированы по сезону.

Если вы отстаете от сезона, возможно, вам стоит рассмотреть возможность расширения данных, чтобы каждый сезон имел только один ряд. Тогда отставание по сезону было бы легко.

Примеры:

Здесь мы используем dcast от «data.table» распространить значения «End.Rank» из «ТИМ». Затем мы отстаем только от вновь созданных столбцов.

library(data.table) 
teams <- as.character(unique(PLRank$Team)) 
dcast(as.data.table(PLRank), Season ~ Team, value.var = "End.Rank")[ 
    , (teams) := lapply(.SD, shift), .SDcols = teams][] 
# Season Deverton Diverpool 
# 1:  1  NA  NA 
# 2:  2  17   8 
# 3:  3  15   4 
# 4:  4  6   3 
# 5:  5  16   4 

Или, если вы хотите как названия команд и значения, чтобы быть в широком виде, вы можете попробовать что-то вроде:

dcast(as.data.table(PLRank)[, ind := sequence(.N), by = Season], 
     Season ~ ind, value.var = c("Team", "End.Rank"))[ 
     , c("End.Rank_1", "End.Rank_2") := lapply(.SD, shift), 
     .SDcols = c("End.Rank_1", "End.Rank_2")][] 
# Season Team_1 Team_2 End.Rank_1 End.Rank_2 
# 1:  1 Diverpool Deverton   NA   NA 
# 2:  2 Diverpool Deverton   8   17 
# 3:  3 Diverpool Deverton   4   15 
# 4:  4 Diverpool Deverton   3   6 
# 5:  5 Diverpool Deverton   4   16 

подход в «dplyr» похож. Поскольку вы идете в широкую форму, вам также нужно «tidyr» для загрузки.

library(dplyr) 
library(tidyr) 
PLRank %>% 
    spread(Team, End.Rank) %>% 
    mutate_each(funs(lag), -Season) 
# Season Deverton Diverpool 
# 1  1  NA  NA 
# 2  2  17   8 
# 3  3  15   4 
# 4  4  6   3 
# 5  5  16   4 
+0

Спасибо! Быстрый вопрос о вашем ответе 'dpylr': как код знает, чтобы отставать от сезона? –

+0

@MattBarger, С Новым Годом! Пожалуйста, ознакомьтесь с моим обновлением и дайте мне знать, если он более полезен для вас. – A5C1D2H2I1M1N2O1R2T1

+0

Спасибо Ананде. У меня есть другие переменные, поэтому я хотел бы сохранить данные в одном столбце.Я предполагаю, что я могу 'spread()', lag, а затем 'gather()' для того же эффекта, правда, верно? –