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?

10
demandé sur zx8754 2017-02-01 21:10:36

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

11
répondu Sam Firke 2017-02-01 18:38:15

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/

8
répondu Philipp Merkle 2017-02-01 18:39:50

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
5
répondu vincentmajor 2017-06-08 00:00:42

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
1
répondu Lloyd Christmas 2017-02-01 18:31:09