Сбор нескольких столбцов

#r #tidyr #tidy #gather

#r #tidyr #аккуратный #сбор

Вопрос:

Я пытаюсь собрать несколько столбцов в R. Примером могут служить некоторые недавние данные о фэнтези-футболе:

 homeId homePlayerName homePosition homeRosterPts awayId awayPlayerName awayPosition awayRosterPts
5      Nick Chubb           RB         23.3         1   Josh Jacobs         RB           8.9
4      Tyreek Hill          WR         24.6         10   Patrick Mahomes    QB           18.5
7      Davante Adams        WR         21.0         2   Michael Thomas      WR           12.4
 

Я хочу, чтобы в каждом столбце было по одному столбцу для идентификатора, имени игрока, очков и столбцов позиций, чтобы я мог приводить в порядок данные и связывать строки вместе — вместо того, чтобы дублироваться для дома и в гостях. Нужно ли мне использовать здесь функцию сбора? Любое решение было бы полезно!

Ответ №1:

Для развлечения / боли / образования, вот как вы можете это сделать с reshape помощью from base R:

 reshape(setNames(df, gsub("(home|away)(.*)", "\2.\1", names(df))), 
        direction = "long", varying = 1:ncol(df))
#        time Id     PlayerName Position RosterPts id
# 1.home home  5      NickChubb       RB      23.3  1
# 2.home home  4     TyreekHill       WR      24.6  2
# 3.home home  7   DavanteAdams       WR      21.0  3
# 1.away away  1     JoshJacobs       RB       8.9  1
# 2.away away 10 PatrickMahomes       QB      18.5  2
# 3.away away  2  MichaelThomas       WR      12.4  3
 

Вы также можете использовать melt из «data.table» следующим образом:

 library(data.table)
nam <- unique(sub("home|away", "", names(df)))
melt(as.data.table(df), measure = patterns(nam), value.name = nam)
#    variable Id     PlayerName Position RosterPts
# 1:        1  5      NickChubb       RB      23.3
# 2:        1  4     TyreekHill       WR      24.6
# 3:        1  7   DavanteAdams       WR      21.0
# 4:        2  1     JoshJacobs       RB       8.9
# 5:        2 10 PatrickMahomes       QB      18.5
# 6:        2  2  MichaelThomas       WR      12.4
 

Ответ №2:

gather удален, использование pivot_longer которого упрощает :

 tidyr::pivot_longer(df, 
                    cols = everything(), 
                    names_to = c('game', '.value'),
                    names_pattern = '(home|away)(.*)')

#  game     Id PlayerName     Position RosterPts
#  <chr> <int> <chr>          <chr>        <dbl>
#1 home      5 NickChubb      RB            23.3
#2 away      1 JoshJacobs     RB             8.9
#3 home      4 TyreekHill     WR            24.6
#4 away     10 PatrickMahomes QB            18.5
#5 home      7 DavanteAdams   WR            21  
#6 away      2 MichaelThomas  WR            12.4
 

данные

 df <- structure(list(homeId = c(5L, 4L, 7L), homePlayerName = c("NickChubb", 
"TyreekHill", "DavanteAdams"), homePosition = c("RB", "WR", "WR"
), homeRosterPts = c(23.3, 24.6, 21), awayId = c(1L, 10L, 2L), 
    awayPlayerName = c("JoshJacobs", "PatrickMahomes", "MichaelThomas"
    ), awayPosition = c("RB", "QB", "WR"), awayRosterPts = c(8.9, 
    18.5, 12.4)), class = "data.frame", row.names = c(NA, -3L))