Как мне создать функцию, которая сравнивает двух игроков набора данных Fifa по нужным мне столбцам?

#r #columnsorting

Вопрос:

Итак, у меня есть набор данных со столбцами, которые включают имя, возраст и намного больше информации об игроках. Я довольно новичок в R и языках программирования в целом.Итак, я не знаю, как написать код, который создает функцию, для которой (1) входные данные: игрок1, игрок (игроки, которых можно найти в столбце «имя») и для которой (2) выходные данные: их данные в столбцах: имя, возраст, общий, позиция и 6 разных оценок навыков (в зависимости от позиции игрока на поле выходные данные должны быть разными (см. 6 точек данных, необходимых для вратарей, и 6 точек данных, необходимых для любой другой позиции в приведенном ниже скрипте). В столбце с именем «Класс» мы можем получить информацию о том, является ли он «Вратарем» или нет. Строки в этом столбце заполнены переменными «Нападающий», «Полузащитник», «Защитник» и «Вратарь»

Я написал это:

 Compare_Players <- Function(Player1, Player2) {
  if ((Player1 == "Goalkeeper")) {
    print(
      Name,
      Age,
      Overall,
      Position,
      GKDiving,
      GKHandling,
      GKKicking,
      GKPositioning,
      GKReflexes,
      Speed,
      Skill.Moves
    )
  } else{
    print(
      Name,
      Age,
      Overall,
      Position,
      Pace,
      Shooting,
      Passing,
      GeneralDribling,
      Defending,
      Physical,
      Skill.Moves
    )
  }
 

Как я хочу, чтобы функция выглядела при использовании: Compare_Players(Messi,Ronaldo)

Результат: оба их данных в вышеупомянутых столбцах

#reprex (вывод> dput(head(df1, 20))

 structure(list(Name = c("L. Messi", "Cristiano Ronaldo", "Neymar Jr", 
"De Gea", "K. De Bruyne", "E. Hazard", "L. Modrić", "L. Suárez", 
"Sergio Ramos", "J. Oblak", "R. Lewandowski", "T. Kroos", "D. Godín", 
"David Silva", "N. Kanté", "P. Dybala", "H. Kane", "A. Griezmann", 
"M. ter Stegen", "T. Courtois"), Age = c(31L, 33L, 26L, 27L, 
27L, 27L, 32L, 31L, 32L, 25L, 29L, 28L, 32L, 32L, 27L, 24L, 24L, 
27L, 26L, 26L), Nationality = c("Argentina", "Portugal", "Brazil", 
"Spain", "Belgium", "Belgium", "Croatia", "Uruguay", "Spain", 
"Slovenia", "Poland", "Germany", "Uruguay", "Spain", "France", 
"Argentina", "England", "France", "Germany", "Belgium"), Overall = c(94L, 
94L, 92L, 91L, 91L, 91L, 91L, 91L, 91L, 90L, 90L, 90L, 90L, 90L, 
89L, 89L, 89L, 89L, 89L, 89L), Potential = c(94L, 94L, 93L, 93L, 
92L, 91L, 91L, 91L, 91L, 93L, 90L, 90L, 90L, 90L, 90L, 94L, 91L, 
90L, 92L, 90L), Club = c("FC Barcelona", "Juventus", "Paris Saint-Germain", 
"Manchester United", "Manchester City", "Chelsea", "Real Madrid", 
"FC Barcelona", "Real Madrid", "Atlético Madrid", "FC Bayern München", 
"Real Madrid", "Atlético Madrid", "Manchester City", "Chelsea", 
"Juventus", "Tottenham Hotspur", "Atlético Madrid", "FC Barcelona", 
"Real Madrid"), Value = c(110500000, 7.7e 07, 118500000, 7.2e 07, 
1.02e 08, 9.3e 07, 6.7e 07, 8e 07, 5.1e 07, 6.8e 07, 7.7e 07, 
76500000, 4.4e 07, 6e 07, 6.3e 07, 8.9e 07, 83500000, 7.8e 07, 
5.8e 07, 53500000), Wage = c(565000, 405000, 290000, 260000, 
355000, 340000, 420000, 455000, 380000, 94000, 205000, 355000, 
125000, 285000, 225000, 205000, 205000, 145000, 240000, 240000
), Preferred.Foot = c("Left", "Right", "Right", "Right", "Right", 
"Right", "Right", "Right", "Right", "Right", "Right", "Right", 
"Right", "Left", "Right", "Left", "Right", "Left", "Right", "Left"
), International.Reputation = c(5, 5, 5, 4, 4, 4, 4, 5, 4, 3, 
4, 4, 3, 4, 3, 3, 3, 4, 3, 4), Weak.Foot = c(4, 4, 5, 3, 5, 4, 
4, 4, 3, 3, 4, 5, 3, 2, 3, 3, 4, 3, 4, 2), Skill.Moves = c(4, 
5, 5, 1, 4, 4, 4, 3, 3, 1, 4, 3, 2, 4, 2, 4, 3, 4, 1, 1), Work.Rate = c("Medium/ Medium", 
"High/ Low", "High/ Medium", "Medium/ Medium", "High/ High", 
"High/ Medium", "High/ High", "High/ Medium", "High/ Medium", 
"Medium/ Medium", "High/ Medium", "Medium/ Medium", "Medium/ High", 
"High/ Medium", "Medium/ High", "High/ Medium", "High/ High", 
"High/ High", "Medium/ Medium", "Medium/ Medium"), Body.Type = c("Messi", 
"C. Ronaldo", "Neymar", "Lean", "Normal", "Normal", "Lean", "Normal", 
"Normal", "Normal", "Normal", "Normal", "Lean", "Normal", "Lean", 
"Normal", "Normal", "Lean", "Normal", "Courtois"), Position = c("RF", 
"ST", "LW", "GK", "RCM", "LF", "RCM", "RS", "RCB", "GK", "ST", 
"LCM", "CB", "LCM", "LDM", "LF", "ST", "CAM", "GK", "GK"), Jersey.Number = c(10, 
7, 10, 1, 7, 10, 10, 9, 15, 1, 9, 8, 10, 21, 13, 21, 9, 7, 22, 
1), Height = c(170, 188, 175, 193, 180, 173, 173, 183, 183, 188, 
183, 183, 188, 173, 168, 178, 188, 175, 188, 198), Weight = c(72, 
83, 68, 76, 70, 74, 66, 86, 82, 87, 80, 76, 78, 67, 72, 75, 89, 
73, 85, 96), Crossing = c(84, 84, 79, 17, 93, 81, 86, 77, 66, 
13, 62, 88, 55, 84, 68, 82, 75, 82, 15, 14), Finishing = c(95, 
94, 87, 13, 82, 84, 72, 93, 60, 11, 91, 76, 42, 76, 65, 84, 94, 
90, 14, 14), HeadingAccuracy = c(70, 89, 62, 21, 55, 61, 55, 
77, 91, 15, 85, 54, 92, 54, 54, 68, 85, 84, 11, 13), ShortPassing = c(90, 
81, 84, 50, 92, 89, 93, 82, 78, 29, 83, 92, 79, 93, 86, 87, 80, 
83, 36, 33), Volleys = c(86, 87, 84, 13, 82, 80, 76, 88, 66, 
13, 89, 82, 47, 82, 56, 88, 84, 87, 14, 12), Dribbling = c(97, 
88, 96, 18, 86, 95, 90, 87, 63, 12, 85, 81, 53, 89, 79, 92, 80, 
88, 17, 13), Curve = c(93, 81, 88, 21, 85, 83, 85, 86, 74, 13, 
77, 86, 49, 82, 49, 88, 78, 84, 18, 19), FKAccuracy = c(94, 76, 
87, 19, 83, 79, 78, 84, 72, 14, 86, 84, 51, 77, 49, 88, 68, 78, 
12, 20), LongPassing = c(87, 77, 78, 51, 91, 83, 88, 64, 77, 
26, 65, 93, 70, 87, 81, 75, 82, 76, 42, 35), BallControl = c(96, 
94, 95, 42, 91, 94, 93, 90, 84, 16, 89, 90, 76, 94, 80, 92, 84, 
90, 18, 23), Acceleration = c(91, 89, 94, 57, 78, 94, 80, 86, 
76, 43, 77, 64, 68, 70, 82, 87, 68, 88, 38, 46), SprintSpeed = c(86, 
91, 90, 58, 76, 88, 72, 75, 75, 60, 78, 62, 68, 64, 78, 83, 72, 
85, 50, 52), Agility = c(91, 87, 96, 60, 79, 95, 93, 82, 78, 
67, 78, 70, 58, 92, 82, 91, 71, 90, 37, 61), Reactions = c(95, 
96, 94, 90, 91, 90, 90, 92, 85, 86, 90, 89, 85, 90, 93, 86, 91, 
90, 85, 84), Balance = c(95, 70, 84, 43, 77, 94, 94, 83, 66, 
49, 78, 71, 54, 90, 92, 85, 71, 80, 43, 45), ShotPower = c(85, 
95, 80, 31, 91, 82, 79, 86, 79, 22, 88, 87, 67, 72, 71, 82, 88, 
80, 22, 36), Jumping = c(68, 95, 61, 67, 63, 56, 68, 69, 93, 
76, 84, 30, 91, 64, 77, 75, 78, 90, 79, 68), Stamina = c(72, 
88, 81, 43, 90, 83, 89, 90, 84, 41, 78, 75, 66, 78, 96, 80, 89, 
83, 35, 38), Strength = c(59, 79, 49, 64, 75, 66, 58, 83, 83, 
78, 84, 73, 88, 52, 76, 65, 84, 62, 79, 70), LongShots = c(94, 
93, 82, 12, 91, 80, 82, 85, 59, 12, 84, 92, 43, 75, 69, 88, 85, 
82, 10, 17), Aggression = c(48, 63, 56, 38, 76, 54, 62, 87, 88, 
34, 80, 60, 89, 57, 90, 48, 76, 69, 43, 23), Interceptions = c(22, 
29, 36, 30, 61, 41, 83, 41, 90, 19, 39, 82, 88, 50, 92, 32, 35, 
35, 22, 15), Positioning = c(94, 95, 89, 12, 87, 87, 79, 92, 
60, 11, 91, 79, 48, 89, 71, 84, 93, 91, 11, 13), Vision = c(94, 
82, 87, 68, 94, 89, 92, 84, 63, 70, 77, 86, 52, 92, 79, 87, 80, 
83, 69, 44), Penalties = c(75, 85, 81, 40, 79, 86, 82, 85, 75, 
11, 88, 73, 50, 75, 54, 86, 90, 79, 25, 27), Composure = c(96, 
95, 94, 68, 88, 91, 84, 85, 82, 70, 86, 85, 82, 93, 85, 84, 89, 
87, 69, 66), Marking = c(33, 28, 27, 15, 68, 34, 60, 62, 87, 
27, 34, 72, 90, 59, 90, 23, 56, 59, 25, 20), StandingTackle = c(28, 
31, 24, 21, 58, 27, 76, 45, 92, 12, 42, 79, 89, 53, 91, 20, 36, 
47, 13, 18), SlidingTackle = c(26, 23, 33, 13, 51, 22, 73, 38, 
91, 18, 19, 69, 89, 29, 85, 20, 38, 48, 10, 16), GKDiving = c(6, 
7, 9, 90, 15, 11, 13, 27, 11, 86, 15, 10, 6, 6, 15, 5, 8, 14, 
87, 85), GKHandling = c(11, 11, 9, 85, 13, 12, 9, 25, 8, 92, 
6, 11, 8, 15, 12, 4, 10, 8, 85, 91), GKKicking = c(15, 15, 15, 
87, 5, 6, 7, 31, 9, 78, 12, 13, 15, 7, 10, 4, 11, 14, 88, 72), 
    GKPositioning = c(14, 14, 15, 88, 10, 8, 14, 33, 7, 88, 8, 
    7, 5, 6, 7, 5, 14, 13, 85, 86), GKReflexes = c(8, 11, 11, 
    94, 13, 8, 9, 37, 11, 89, 10, 10, 15, 12, 10, 8, 11, 14, 
    90, 88), League = c("La Liga", "Serie A", "Ligue 1", "Premier League", 
    "Premier League", "Premier League", "La Liga", "La Liga", 
    "La Liga", "La Liga", "Bundesliga", "La Liga", "La Liga", 
    "Premier League", "Premier League", "Serie A", "Premier League", 
    "La Liga", "La Liga", "La Liga"), `Country/competition` = c("Spain", 
    "Italy", "France", "UK", "UK", "UK", "Spain", "Spain", "Spain", 
    "Spain", "Germany", "Spain", "Spain", "UK", "UK", "Italy", 
    "UK", "Spain", "Spain", "Spain"), Class = c("Forward", "Forward", 
    "Forward", "Goalkeeper", "Midfielder", "Forward", "Midfielder", 
    "Forward", "Defender", "Goalkeeper", "Forward", "Midfielder", 
    "Defender", "Midfielder", "Midfielder", "Forward", "Forward", 
    "Midfielder", "Goalkeeper", "Goalkeeper"), Pace = c(88, 90, 
    92, 58, 77, 91, 76, 80, 75, 52, 78, 63, 68, 67, 80, 85, 70, 
    86, 45, 49), Shooting = c(91, 93, 84, 18, 86, 83, 76, 89, 
    65, 14, 89, 82, 48, 76, 66, 85, 90, 86, 15, 20), Passing = c(90, 
    81, 83, 44, 92, 86, 90, 79, 72, 32, 75, 89, 65, 89, 77, 84, 
    79, 82, 37, 30), GeneralDribbling = c(96, 89, 95, 32, 87, 
    95, 92, 87, 72, 21, 85, 83, 62, 91, 80, 92, 80, 88, 21, 23
    ), Defending = c(32, 35, 32, 20, 61, 35, 70, 52, 90, 19, 
    41, 74, 89, 52, 87, 28, 47, 52, 18, 17), Physical = c(60, 
    79, 59, 54, 78, 67, 67, 85, 85, 60, 82, 69, 83, 60, 84, 66, 
    83, 70, 61, 52), Speed = c(89, 90, 92, 57, 77, 92, 77, 82, 
    76, 50, 77, 63, 68, 68, 80, 85, 70, 87, 43, 48)), row.names = c(NA, 
20L), class = "data.frame")
 

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

1. пожалуйста, предоставьте reprex

2. Вы можете предоставить воспроизводимый пример («reprex»), вставив сюда выходные данные из dput(head(df1, 20))

3. Результат был слишком большим для комментариев, поэтому я отредактировал исходное сообщение и добавил результат

Ответ №1:

Вот еще один вариант:

 library(tidyverse)

Compare_Players <- function(data, Player1, Player2){
  
  stats <- c("Name", "Age", "Overall", "Position", "Pace", "Shooting", "Passing", "GeneralDribling", "Defending", "Physical", "Skill.Moves",
             "GKDiving", "GKHandling", "GKKicking", "GKPositioning", "GKReflexes", "Speed", "Skill.Moves")
  
  df %>% 
    filter(Name == !!enquo(Player1) | Name == !!enquo(Player2)) %>% 
    select(any_of(stats))
}


Compare_Players(df, "L. Messi", "De Gea")
 

Это дает нам:

       Name Age Overall Position Pace Shooting Passing Defending Physical Skill.Moves GKDiving GKHandling GKKicking GKPositioning GKReflexes Speed
1 L. Messi  31      94       RF   88       91      90        32       60           4        6         11        15            14          8    89
2   De Gea  27      91       GK   58       18      44        20       54           1       90         85        87            88         94    57
 

Редактировать:

Если вы хотите видеть двух игроков и разные статистические данные, вы можете объединить их в a list , но это немного сложнее:

 Compare_Players <- function(data, Player1, Player2){
  
  p1 <- data %>% 
    filter(Name == !!enquo(Player1))
  
  p2 <- data %>% 
    filter(Name == !!enquo(Player2))
  
  gk_stats <- c("Name", "Age", "Overall", "Position", "GKDiving", "GKHandling", "GKKicking", "GKPositioning", "GKReflexes", "Speed", "Skill.Moves")
  
  stats <- c("Name", "Age", "Overall", "Position", "Pace", "Shooting", "Passing", "GeneralDribling", "Defending", "Physical", "Skill.Moves")
  
if (p1$Class == "Goalkeeper"){
  p1 <- p1 %>% select(any_of(gk_stats))
} else {
  p1 <- p1 %>% select(any_of(stats))
}
  
  if (p2$Class == "Goalkeeper"){
    p2 <- p2 %>% select(any_of(gk_stats))
  } else {
    p2 <- p2 %>% select(any_of(stats))
  }  
  
  out <- list(p1,p2)
  out
  
}
 

Что дает нам:

 > Compare_Players(df, "L. Messi", "De Gea")
[[1]]
      Name Age Overall Position Pace Shooting Passing Defending Physical Skill.Moves
1 L. Messi  31      94       RF   88       91      90        32       60           4

[[2]]
    Name Age Overall Position GKDiving GKHandling GKKicking GKPositioning GKReflexes Speed Skill.Moves
1 De Gea  27      91       GK       90         85        87            88         94    57           1
 

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

1. Это здорово! Однако разве это не будет также отображать навыки вратаря, даже если сравнивать игроков, например, с двумя нападающими?

2. Да, это было бы. Что бы вы хотели увидеть, если бы игрок1 не был вратарем, а игрок2 был?

3. Именно это, но без печати нерелевантных статистических данных для соответствующего игрока. Сравнение в этом случае больше не является сравнением, поскольку статистика собирается из разных столбцов, да. Но я пытаюсь сделать так, чтобы он выглядел как можно более чистым.

4. Обратите внимание, что в именах переменных reprex нет общего дриблинга

Ответ №2:

Без reprex остается только догадываться, как выглядят ваши данные. Предполагая, что у вас есть NA значения для переменных, которые не применимы к игрокам, как в этом наборе данных toy .

 library(tidyverse)
#df <- tibble(Name = c("Messi", "Ronaldo", "RandomGuy"),
 #            Position = c("Somewhere", "Elsehwere", "Goalkeeper"),
  #           Pace = c(999, 555, NA),
   #          GKHandling = c(NA, NA, 15)
    #         )
df <- OP's reprex
 

Затем мы можем использовать rlang пакет nice, чтобы указать произвольное количество игроков для сравнения, привести в порядок данные tidyr и использовать подмножество данных dplyr .

 Compare_Players <- function(df, ...){
  gk_stats <- c("First_name", "Surname", "Age", "Overall", "Position", "GKDiving", "GKHandling", "GKKicking", "GKPositioning", "GKReflexes", "Speed", "Skill.Moves")
  stats <- c("First_name", "Surname",  "Age", "Overall", "Position", "Pace", "Shooting", "Passing", "Defending", "Physical", "Skill.Moves")
  
  players <- ensyms(...)
  df %>%
    extract(Name, into = c("First_name", "Surname"), "^(.* )(.*)") %>%
    filter(Surname %in% !!players) %>%
    select({if("GK" %in% .$Position) gk_stats else stats})
}
 

Это позволяет нам записывать игроков без кавычек непосредственно в вызове функции.
Подробное объяснение того, как это работает, см. в [Advanced R][1]. Короче говоря, он принимает аргументы, переданные ... , и преобразует их так, чтобы filter функция знала, что это вектор символов.

Теперь мы можем вызвать Compare_Players(df, Messi, Ronaldo) , что дает

 
# A tibble: 2 x 11
  First_name Surname   Age Overall Position  Pace Shooting Passing Defending Physical Skill.Moves
  <chr>      <chr>   <int>   <int> <chr>    <dbl>    <dbl>   <dbl>     <dbl>    <dbl>       <dbl>
1 L.         Messi      31      94 RF          88       91      90        32       60           4
2 Cristiano  Ronaldo    33      94 ST          90       93      81        35       79           5

 

Два предостережения — если у игрока есть a Surname , который содержит пробелы, выбирается сегмент фамилии. Для этого небольшого набора это не проблема, но если у вас есть дубликаты в наборе, вы можете применить дополнительную фильтрацию или точно настроить регулярное выражение в extract вызове. Наконец, вызов Compare_Players(df, Messi, Gea) возвращает

 # A tibble: 2 x 12
  First_name Surname   Age Overall Position GKDiving GKHandling GKKicking GKPositioning GKReflexes Speed Skill.Moves
  <chr>      <chr>   <int>   <int> <chr>       <dbl>      <dbl>     <dbl>         <dbl>      <dbl> <dbl>       <dbl>
1 L.         Messi      31      94 RF              6         11        15            14          8    89           4
2 De         Gea        27      91 GK             90         85        87            88         94    57           1
 

Поэтому остерегайтесь неинформативных вызовов, так как функция будет возвращаться независимо
[1]: https://adv-r.hadley.nz/quasiquotation.html

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

1. Я отредактировал свой вопрос, чтобы сделать его более осмысленным, и попытался добавить reprex. Набор данных, который я использую, — это набор данных статистики игроков fifa19. (очень легко найти, если предоставленный мной reprex не соответствует тому, что вы просили) Однако я сам вычислил некоторые столбцы, используемые в функции (например, темп (состоящий из столбцов (1) Скорость бега * 0,55 (2) Ускорение * 0,45)).

2. Ваш Name столбец беспорядочный. Некоторые имена сокращены, другие — нет. К функции необходимо добавить дополнительный шаг, чтобы она снова заработала, поскольку пробелы в квазинотации не работают. Я отредактировал ответ.