My dataframe (df) contient une liste de valeurs qui sont étiquetées suivant un format de «Mois», «Nom du site» et «N ° de caméra». Par exemple, si ma valeur est 'DECBUTCAM27', alors Dec-Decembre, MAIS-Nom du site et CAM27-Camera No.
J'ai 100 de ces valeurs avec 19 noms de sites différents.
Je veux écrire un code If else de sorte que seuls les noms de sites soient reconnus et qu'un numéro correspondant soit ajouté.
Mon idée initiale était d'ajouter le numéro correspondant pour toutes les 100 valeurs, mais puisque si le reste ne fonctionne pas au-delà de 50 valeurs, je ne pourrais pas utiliser cette option.
Voici ce que j'avais écrit pour l'option que j'avais essayée:
df <- df2 %>% mutate(Site_ID = ifelse (CT_Name == 'DECBUTCAM27', "1", ifelse (CT_Name == 'DECBUTCAM28', "1", ifelse (CT_Name == 'DECI2NCAM01', "2", ifelse (CT_Name == 'DECI2NCAM07', "2", ifelse (CT_Name == 'DECI5CAM39', "3", ifelse (CT_Name == 'DECI5CAM40', "3","NoVal")))))))
Je recherche un code tel que seuls les sites, c'est-à-dire «MAIS», «I2N» et «I5», soient reconnus et un numéro correspondant est ajouté.
Toute aide serait grandement appréciée.
3 Réponses :
Voici un exemple rapide utilisant regex pour trouver le code du site et utilisant une fonction apply pour renvoyer un vecteur de code.
df <- data.frame(code = c('DECBUTCAM27','JANBUTCAM27','DECDUCCAM45')) df$n <- apply(df, 1, function(x) switch(gsub("CAM.*$","",gsub("^.{3}",'',x[1])), BUT = 1, DUC = 2) )
Attention, j'utilise ici le x[1]
car le code est dans la première colonne de mon data.frame, qui peut varier pour vous.
--- EDIT --- C'était une réponse précédente fonctionnant également mais avec plus de travail à faire. Cependant, il vous permet de choisir une valeur de code numérique (ou du texte) pour attribuer des emplacements s'ils sont commandés par exemple.
Il vous faut mettre tous les codes pour chaque site, ce que j'ai trouvé lourd en terme de code mais ça marche. La partie interrupteur est à peu près la même qu'un ifelse.
La regex consiste à exclure les 3 premiers caractères et les autres à la fin après la séquence 'CAM'.
df <- data.frame(code = c('DECBUTCAM27','JANBUTCAM27','DECDUCCAM45')) df$loc <- apply(df, 1, function(x) gsub("CAM.*$","",gsub("^.{3}",'',x[1]))) unique(df$loc) #Â all the location of the file df$n <- as.numeric(as.factor(df$loc)) # get a number for each location
Voici une solution tidyverse
:
# A tibble: 6 x 4 # Groups: Site [3] Month Site Camera Site_ID <chr> <chr> <chr> <int> 1 DEC BUT CAM27 1 2 DEC BUT CAM28 1 3 DEC I2N CAM01 2 4 DEC I2N CAM07 2 5 DEC I5 CAM39 3 6 DEC I5 CAM40 3
tidyr
extract()
tidyr
pour diviser la chaîne en ses composants:data_new <- data %>% extract(CT_Name, regex = "(\\w{3})(\\w{2,})(CAM\\d+)", into = c("Month", "Site", "Camera")) %>% group_by(Site) %>% mutate(Site_ID = cur_group_id())
(ajoutez remove = FALSE
si vous souhaitez conserver la variable CT_Name d'origine)
Cela donne:
# A tibble: 6 x 3 Month Site Camera <chr> <chr> <chr> 1 DEC BUT CAM27 2 DEC BUT CAM28 3 DEC I2N CAM01 4 DEC I2N CAM07 5 DEC I5 CAM39 6 DEC I5 CAM40
data_new <- data %>% extract(CT_Name, regex = "(\\w{3})(\\w{2,})(CAM\\d+)", into = c("Month", "Site", "Camera"))
Cela produit:
data <- tribble( ~ CT_Name, "DECBUTCAM27", "DECBUTCAM28", "DECI2NCAM01", "DECI2NCAM07", "DECI5CAM39", "DECI5CAM40" )
Extrayez le nom du site à l'aide de regex et utilisez match
+ unique
pour attribuer un numéro unique.
CT_Name <- c('DECBUTCAM27', 'DECBUTCAM28', 'DECI2NCAM07', 'DECI2NCAM01', 'DECI5CAM39', 'DECI5CAM40') site_name <- sub('...(.*)CAM.*', '\\1', CT_Name) site_name #[1] "BUT" "BUT" "I2N" "I2N" "I5" "I5" Site_ID <- match(site_name, unique(site_name)) Site_ID #[1] 1 1 2 2 3 3
Par exemple, voyez cet exemple:
df2$site_name <- sub('...(.*)CAM.*', '\\1', df2$CT_Name) df2$Site_ID <- match(df2$site_name, unique(df2$site_name))
Pouvez-vous expliquer ce que votre sous-marin fait avec '\\1'
? Je n'ai jamais vu ça avant et ça a l'air intéressant ^^
Il est utilisé comme référence arrière pour capturer le motif dans le groupe de capture qui est ici (.*)