Estoy intentando escribir una función que calcule una puntuación a partir de las divisiones de un jugador de béisbol. He creado el Tibble dividido, un Tibble funcional y una función para usar junto con la función mutar para agregar una columna de puntuación al Tibble funcional, df.
Se supone que la función toma la información del Tibble en funcionamiento y calcula una puntuación (suma de promedios) basada en las divisiones relevantes. He proporcionado el siguiente reprex. Cuando intento ejecutar mi función, obtengo puntuaciones de cero. Los valores de puntuación esperados siguen el reprex.
¿Alguien puede decirme qué estoy haciendo mal?
library(tidyverse)
split <- tibble(player=c("Soto","Soto","Judge","Judge","Soto","Soto","Judge","Judge"),
split=c("Grass","Turf","Grass","Turf","DAY","NIGHT", "DAY","NIGHT"),
AVG=c(200,225,250,275,300,325,350,375))
df <- tibble(date = c("2021-03-24", "2021-03-27", "2021-03-21", "2021-03-25"), player=c("Soto","Soto", "Judge", "Judge"), TOD=c("DAY","DAY","DAY","NIGHT"), surface=c("Grass","Turf","Turf","Grass"))
split
#> # A tibble: 8 x 3
#> player split AVG
#> <chr> <chr> <dbl>
#> 1 Soto Grass 200
#> 2 Soto Turf 225
#> 3 Judge Grass 250
#> 4 Judge Turf 275
#> 5 Soto DAY 300
#> 6 Soto NIGHT 325
#> 7 Judge DAY 350
#> 8 Judge NIGHT 375
df
#> # A tibble: 4 x 4
#> date player TOD surface
#> <chr> <chr> <chr> <chr>
#> 1 2021-03-24 Soto DAY Grass
#> 2 2021-03-27 Soto DAY Turf
#> 3 2021-03-21 Judge DAY Turf
#> 4 2021-03-25 Judge NIGHT Grass
getSplitScore <- function(df,player,surface, timeofDay){
z <- sum(df[df$player==player & df$split==timeofDay,]$AVG)
y <- sum(df[df$player==player & df$split==surface,]$AVG)
return(z + y)
}
df <- df %>%
mutate(score=getSplitScore(split, player, surface, TOD))
df
#> # A tibble: 4 x 5
#> date player TOD surface score
#> <chr> <chr> <chr> <chr> <int>
#> 1 2021-03-24 Soto DAY Grass 0
#> 2 2021-03-27 Soto DAY Turf 0
#> 3 2021-03-21 Judge DAY Turf 0
#> 4 2021-03-25 Judge NIGHT Grass 0
Creado el 27-03-2021 por el paquete reprex (v0.3.0)
Lo que espero es esto:
#> # A tibble: 4 x 5
#> date player TOD surface score
#> <chr> <chr> <chr> <chr> <int>
#> 1 2021-03-24 Soto DAY Grass 500
#> 2 2021-03-27 Soto DAY Turf 525
#> 3 2021-03-21 Judge DAY Turf 625
#> 4 2021-03-25 Judge NIGHT Grass 625
1
No tienes una columna BaVG en el tibble dividido. Tampoco estoy seguro de cómo se llega a los valores de puntuación.
- WilliamGram
27/03/2021 a las 20:39
En el resultado deseado, la puntuación de 200 es la suma de Soto Day & ¿Soto TOD? Sólo necesito un ejemplo de cómo se calcula la puntuación.
Anoushiravan R.
27/03/2021 a las 20:41
La puntuación es simplemente la suma del BaVG a dividir/
Mutualinvestor
27/03/2021 a las 23:57
@WilliamGram Buen partido. A veces puedes estar demasiado cerca de las cosas. ¡Gracias!
Mutualinvestor
28 de marzo de 2021 a las 0:02
------------------------------------
Agregar un group_by antes de ejecutar mutate en pipe funcionará. Ver
df %>% group_by(date, player) %>%
mutate(score= getSplitScore(split, player, surface, TOD))
# A tibble: 4 x 5
# Groups: date, player [4]
date player TOD surface score
<chr> <chr> <chr> <chr> <dbl>
1 2021-03-24 Soto DAY Grass 500
2 2021-03-27 Soto DAY Turf 525
3 2021-03-21 Judge DAY Turf 625
4 2021-03-25 Judge NIGHT Grass 625
Estrategia alternativa propuesta
df %>% left_join(split, by = c("player" = "player", "TOD" = "split")) %>%
rbind(df %>% left_join(split, by = c("player" = "player", "surface" = "split"))) %>%
group_by(date, player, TOD, surface) %>%
summarise(AVG = sum(AVG))
# A tibble: 4 x 5
# Groups: date, player, TOD [4]
date player TOD surface AVG
<chr> <chr> <chr> <chr> <dbl>
1 2021-03-21 Judge DAY Turf 625
2 2021-03-24 Soto DAY Grass 500
3 2021-03-25 Judge NIGHT Grass 625
4 2021-03-27 Soto DAY Turf 525
2
Gracias por la respuesta. Se supone que mi función hace referencia al df dividido. No estoy tratando de resumir columnas en df, estoy tratando de calcular una puntuación de la columna AVG en la división cuando la superficie y la hora del día en df y la división coinciden.
Mutualinvestor
28 de marzo de 2021 a las 8:26
1
Sí. Entiendo. Vea mi respuesta revisada. Simplemente agregue un group_by antes de mutar en dplyr pipe y funcionará.
AnilGoyal
28 de marzo de 2021 a las 8:27
------------------------------------
Comenzaría dividiendo la columna split$split en territorio y día. Un enfoque menos elegante:
split <- split %>%
mutate(
TOD = ifelse(split %in% c('DAY', 'NIGHT'), split, 'NA'),
surface = ifelse(split %in% c('Grass', 'Turf'), split, 'NA'),
.keep = 'unused'
)
Entonces puedes dejar de unirte:
df <- df %>%
left_join(
split %>% select(-surface) %>% rename(todVal = AVG), by = c('player', 'TOD')
) %>%
left_join(
split %>% select(-TOD) %>% rename(surfaceVal = AVG), by = c('player', 'surface')
) %>%
mutate(score = (todVal + surfaceVal), .keep='unused')
El resultado que deberías obtener:
df
# date player TOD surface score
# 1 2021-03-24 Soto DAY Grass 500.0
# 2 2021-03-27 Soto DAY Turf 525.0
# 3 2021-03-21 Judge DAY Turf 625.0
# 4 2021-03-25 Judge NIGHT Grass 625.0
Veo que el resultado no es el que querías, pero tal vez deberías intentar ser un poco más claro en lo que estás buscando.tratando de hacer.