2 votes

Comment détecter une cellule contenant une chaîne de caractères et les 2 cellules suivantes dans un cadre de données ?

Je me demande comment détecter une chaîne de caractères dans un cadre de données R et les 2 ( ou n ) cellules suivantes de la même ligne. Et après la détection, mon but serait de produire une variable indicatrice à partir de ces 3 cellules.

Il est beaucoup plus facile de montrer ce que je veux dire en produisant un exemple. Disons que mon cadre de données ressemble à ceci

table <-  data.frame( x1 = c(1,4,6,"Y"), x2 = c("Y",1,"Y",5), x3 = c(1,2,5,4),
                     x4 = c(2,NA,4,"Y"), x5 = c(NA,NA,6,1), x6 = c(NA,NA,1,5))
x1 x2 x3 x4 x5 x6
1  Y  1  2 NA NA
4  1  2  NA NA NA
6  Y  5  4  6  1
Y  5  4  Y  1  5

Et le but serait un tableau qui ressemble à quelque chose comme ceci

goal_table <- data.frame(Y12 = c(1,0,0,0),Y54 = c(0,0,1,1), Y15 = c(0,0,0,1))

Y12 Y54 Y15
1   0   0
0   0   0
0   1   0
0   1   1

Ainsi, étant donné que dans le tableau original, la première ligne contient la cellule "Y" suivie de "1" et "2", le tableau cible aurait alors la colonne "Y12" avec l'indicateur 1 et appliquerait la même logique à toutes les autres combinaisons de deux chiffres qui suivent "Y".

Quelques informations qui pourraient vous faciliter la tâche : Y est toujours suivi d'au moins deux chiffres. Si une ligne contient NA, par exemple x2, tous les x3, x4, x5,... suivants seront également NA (comme dans l'exemple). Le tableau d'objectifs ne doit pas nécessairement être un tableau à part entière, les colonnes peuvent simplement être ajoutées au tableau original.

1voto

akrun Points 148302

Voici une option avec tidyverse

library(dplyr)
library(tidyr)
library(stringr)
table %>% 
   mutate_all(as.character) %>% 
   mutate(rn = row_number()) %>%
   pivot_longer(cols = -rn, values_drop_na = TRUE) %>% 
   group_by(rn) %>% 
   group_by(grp = cumsum(value == 'Y'), add = TRUE) %>%
   summarise(value = str_c(head(value, 3), collapse="")) %>% 
   filter(str_detect(value, '^Y')) %>% 
   ungroup %>%
   select(-grp) %>%
   mutate(new = 1) %>%
   group_by(rn) %>%
   mutate(rn2 = row_number()) %>%
   ungroup %>%
   pivot_wider(names_from = value, values_from = new, 
           values_fill = list(new = 0)) %>%
   select(-rn, - rn2)
# A tibble: 4 x 3
#    Y12   Y54   Y15
#  <dbl> <dbl> <dbl>
#1     1     0     0
#2     0     1     0
#3     0     1     0
#4     0     0     1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X