0
votes

Instruction If else avec une valeur faisant partie d'un caractère continu dans R

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.


0 commentaires

3 Réponses :


1
votes

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


0 commentaires

1
votes

Voici une solution tidyverse :

  1. Vous n'avez pas fourni d'exemple reproductible, mais utilisons les CT_Names que vous avez fournis pour créer une trame de données de test:
# 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
  1. Supposons que le format de chaîne soit de 3 lettres pour les mois, 2 lettres ou plus ou plus pour le site et CAM + 1 ou plusieurs chiffres pour le numéro de caméra (ajustez-les si nécessaire). Nous pouvons utiliser une expression régulière dans la 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
  1. Nous pouvons ensuite regrouper par site et attribuer un identifiant de groupe comme votre Site_ID:
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"
  )


0 commentaires

2
votes

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


2 commentaires

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 (.*)