Créer une nouvelle colonne avec dplyr muter et la sous-couche de la colonne existante
j'ai un dataframe avec une colonne de chaînes et souhaitez extraire des sous-chaînes de ces dans une nouvelle colonne.
voici un exemple de code et de données montrant que je veux prendre la chaîne après le caractère de soulignement final dans le id
colonne pour créer un new_id
colonne.
id
l'entrée de colonne a toujours 2 caractères de soulignement et c'est toujours le substrat final 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 strsplit d'agir sur chaque ligne tourner.
cependant, le new_id
colonne ne contient que ABC
dans chaque rangée, alors que je voudrais ABC
dans la rangée 1 et NHYK
dans la rangée 2. Savez-vous pourquoi cela échoue et comment atteindre ce que je veux?
4 réponses
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
La regex dit, correspondre à un ou plusieurs (+
) des caractères ne sont pas_
(la négation [^ ]
), suivie par la fin de la chaîne ($
).
Utiliser 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/
une alternative sans regex et le maintien dans le tidyverse
le style est d'utiliser tidyr::separate()
. Note: Ceci supprime la colonne input par défaut (remove=FALSE
pour éviter cela).
## 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
Voici une façon d'utiliser strsplit
d'une 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