web-dev-qa-db-fra.com

Créer une nouvelle colonne avec dplyr mutate et sous-chaîne de la colonne existante

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?

15
PM.

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

17
Sam Firke

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
9
vincentmajor

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/

8
Philipp Merkle

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
1
Lloyd Christmas