J'ai des données de hockey, appelées df
library(purrr) df %>% group_by(id) %>% map_dfr(rbind, NA) %>% mutate(id = rep(df$id, each = 2))
Comment puis-je créer des lignes après chaque ligne, me laissant avec 57 * 2 (114 lignes), mais les valeurs de mes lignes nouvellement créées dépendent de la colonne event_rinkside
.
event_rinkside
vaut R
, alors, je souhaite insérer 82
dans coords_x
et 0
dans coords_y
. event_rinkside
est égal à L
, alors, je veux insérer -82
dans coords_x
et 0
en coords_y
. Je pense que la solution à cette question SO a> est un bon point de départ, mais je ne sais pas comment incorporer mes propres conditions:
Voici la solution dont je parle:
structure(list(event_index = 1:57, coords_x = c(80, 53, 31, -56, -34, -33, -40, 30, -66, -36, 45, 17, -6, 47, -51, -31, -69, -86, -70, 80, 65, -76, -71, 81, -57, 80, 75, 77, -71, -40, -83, 62, 77, 76, NA, -61, 69, -45, 68, 31, 58, 61, 80, 34, 80, -85, -37, -57, 76, 14, 49, -82, -34, -36, -83, -84, -55), coords_y = c(-1, 14, -30, 17, 26, -23, -37, 17, -32, -18, 25, 17, -38, 21, 28, 22, 17, 13, 10, -37, -17, 9, 18, -11, 21, -7, 3, 3, -38, 31, 8, -30, -2, 4, NA, -5, 15, 10, -30, -34, 20, 27, -4, 8, -18, 19, 32, -21, 0, 40, -4, -30, -24, -28, -2, -3, 34), event_rinkside = c("R", "R", "R", "L", "L", "L", "L", "R", "L", "L", "R", "N", "N", "R", "L", "L", "L", "L", "L", "R", "R", "L", "L", "R", "L", "R", "R", "R", "L", "L", "L", "R", "R", "R", NA, "L", "R", "L", "R", "R", "R", "R", "R", "R", "R", "L", "L", "L", "R", "N", "R", "L", "L", "L", "L", "L", "L")), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -57L))
4 Réponses :
Je ne suis pas trop familier avec r, mon algorithme devrait fonctionner indépendamment de cela. Vous souhaitez déplacer la ligne vers la ligne 2n-1. Je créerais un deuxième tableau et les placerais manuellement dans les index spécifiques.
un pseudo code pour vous (j'écris généralement en python donc mon pseudo le montre)
reinsert(list): array_out = [len(list)*2,len(list[0]) // initialize to the desired dimensions array_out[0] = list[0] /// manually insert first row cause math for n in range(0,len(list)): array_out[2n-1] = list[n] array_out[2n] = event_rinkside // make a function call or make an ifthen clause to do you logic return(array_out)
vous pouvez insérer les lignes nouvellement créées dans la boucle ou les ajouter après le fait sachant qu'ils seront tous à des index pairs.
Voici une solution avec dplyr
:
# A tibble: 114 x 4 event_index coords_x coords_y event_rinkside <int> <dbl> <dbl> <chr> 1 1 80 -1 R 2 1 82 0 R 3 2 53 14 R 4 2 82 0 R 5 3 31 -30 R 6 3 82 0 R 7 4 -56 17 L 8 4 -82 0 L 9 5 -34 26 L 10 5 -82 0 L # ⦠with 104 more rows
Comment ça marche:
Dans la première étape, mutate
est utilisé pour modifier une copie non attribuée de df
. La colonne coords_x
prend la valeur 82; la valeur est multipliée par -1 si event_rinkside == "L"
et 1 sinon. La colonne coords_y
prend la valeur 0.
À l'étape suivante, le bloc de données d'origine inchangé df
et la copie actuelle non attribuée et modifiée de celui-ci sont combinés avec rbind
. Ici, .
représente le résultat de l'étape mutate
ci-dessus. Le résultat de rbind
a les lignes de la version originale au-dessus des lignes de la version modifiée.
Dans la dernière étape, arrange
est utilisé pour trier les lignes le long des valeurs de event_index
. De cette façon, chaque ligne d'origine est directement suivie de la ligne modifiée correspondante.
Le résultat:
library(dplyr) df %>% mutate(coords_x = 82 * ifelse(event_rinkside == "L", -1, 1), coords_y = 0) %>% rbind(df, .) %>% arrange(event_index)
Pourriez-vous expliquer la logique qui a conduit à cela?
Je l'ai compris après l'avoir parcouru pas à pas. Sven muter
d coords_x
et coords_y
avec les valeurs souhaitées: (82, 0) pour R et (-82, 0) pour L. Puis , il a joint le jeu de données d'origine avec rbind
puis arrange
d par event_index pour formater le jeu de données de la manière que je voulais. Vraiment simple, mais brillant
@NelsonGon J'ai ajouté une explication.
@JasonBaik J'ai ajouté une explication.
Ceci est similaire à la réponse de Sven, en utilisant case_when
pour distinguer les possibilités dans event_rinkside
:
new_df <- df %>% bind_rows( df %>% mutate( coords_x = case_when( event_rinkside == 'R' ~ 82, event_rinkside == 'L' ~ -82, TRUE ~ coords_x ), coords_y = case_when( event_rinkside == 'R' ~ 0, event_rinkside == 'L' ~ 0, TRUE ~ coords_y ) ) ) %>% arrange( event_index )
Si vous connaissez les plages de vos variables, il pourrait être simplifié en if_else
s.
Ma tentative, qui est assez similaire à d'autres réponses déjà,
df <- df[rep(1:nrow(df), each = 2),] ## Create a duplicate row after each row df[seq(2,nrow(df),2),] <- df[seq(2,nrow(df),2),] %>% mutate(coords_x = case_when(event_rinkside == "R" ~ 82, event_rinkside == "L" ~ -82, TRUE ~ coords_x), coords_y = case_when(event_rinkside == "R" ~ 0, event_rinkside == "L" ~ 0, TRUE ~ coords_y) )