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_elses.
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)
)