#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
столбец беспорядочный. Некоторые имена сокращены, другие — нет. К функции необходимо добавить дополнительный шаг, чтобы она снова заработала, поскольку пробелы в квазинотации не работают. Я отредактировал ответ.