J'ai une trame de données avec une colonne de chaînes et je souhaite extraire des sous-chaînes de celles-ci dans une nouvelle colonne.
Voici quelques exemples de code et de données montrant que je veux prendre la chaîne après le dernier caractère de soulignement dans la colonne id
afin de créer un new_id
colonne. L'entrée de colonne id
a toujours 2 caractères de soulignement et c'est toujours la sous-chaîne finale que je voudrais.
df = data.frame( id = I(c("abcd_123_ABC","abc_5234_NHYK")), x = c(1.0,2.0) )
require(dplyr)
df = df %>% dplyr::mutate(new_id = strsplit(id, split="_")[[1]][3])
Je m'attendais à ce que strsplit agisse à tour de rôle sur chaque ligne.
Cependant, le new_id
la colonne ne contient que ABC
dans chaque ligne, alors que je voudrais ABC
dans la ligne 1 et NHYK
dans la ligne 2. Savez-vous pourquoi cela échoue et comment y parvenir Je voudrais?
Vous pouvez utiliser stringr::str_extract
:
library(stringr)
df %>%
dplyr::mutate(new_id = str_extract(id, "[^_]+$"))
#> id x new_id
#> 1 abcd_123_ABC 1 ABC
#> 2 abc_5234_NHYK 2 NHYK
Le regex dit, correspond à un ou plusieurs (+
) des caractères qui ne le sont pas_
(la négation [^ ]
), suivi de la fin de la chaîne ($
).
Une alternative sans regex et en conservant le style tidyverse
est d'utiliser tidyr::separate()
. Notez que cela supprime la colonne d'entrée par défaut (remove=FALSE
pour l'empêcher).
## using your example data
df = data.frame( id = I(c("abcd_123_ABC","abc_5234_NHYK")), x = c(1.0,2.0) )
## separate knowing you will have three components
df %>% separate(id, c("first", "second", "new_id"), sep = "_") %>% select(-first, -second)
## returns
new_id x
1 ABC 1
2 NHYK 2
Utilisation dplyr::rowwise
:
df %>% dplyr::rowwise() %>% dplyr::mutate(new_id = strsplit(id, split="_")[[1]][3])
D'autres alternatives sont discutées ici:
http://www.expressivecode.org/2014/12/17/mutating-using-functions-in-dplyr/
Voici une façon d'utiliser strsplit
de manière générale pour faire ce que vous cherchez.
library(dplyr)
df = data.frame( id = I(c("abcd_123_ABC","abc_5234_NHYK")), x = c(1.0,2.0) )
temp <- seq(from=3, by=3, length.out = length(df))
dfn <- df %>% dplyr::mutate(new_id = unlist(strsplit(id, split="_"))[temp])
> dfn
id x new_id
1 abcd_123_ABC 1 ABC
2 abc_5234_NHYK 2 NHYK