如何正确组合mutate和str_match?

问题描述 投票:0回答:2

假设我想将字符串列拆分为单独的列。为此,我使用 stringr 包中的 mutate 和 str_match (或 str_replace),但结果不符合预期。

设置数据框并拆分列:

df <-
  data.frame(strings = c('a_b_c', 'ab_cd_ef', 'abc_def_ghi')) %>%
  mutate(string = stringr::str_match(strings, '([a-z]+)_([a-z]+)_([a-z]+)')) 

df
      strings    string.1 string.2 string.3 string.4
1       a_b_c       a_b_c        a        b        c
2    ab_cd_ef    ab_cd_ef       ab       cd       ef
3 abc_def_ghi abc_def_ghi      abc      def      ghi

查看列名称时,我只看到两列。这也使得引用列变得复杂。我认为它与 str_match 函数输出的矩阵格式有关。

df %>% ncol
[1] 2

df %>% colnames
[1] "strings" "string"

有没有一种简单的方法可以让这个新列的行为像普通的 data.frame 列一样?如果可能,请执行重命名步骤。这是我想要拥有的东西:

df %>% ncol
[1] 5

df %>% colnames
[1] "strings" "string_1" "string_2" "string_3" "string_4"

df
      strings    string_1 string_2 string_3 string_4
1       a_b_c       a_b_c        a        b        c
2    ab_cd_ef    ab_cd_ef       ab       cd       ef
3 abc_def_ghi abc_def_ghi      abc      def      ghi

r stringr dplyr
2个回答
1
投票

以最通用的形式回答原始问题:

str_match()
生成一个字符矩阵。我们可以使用
as_tibble
.name_repair
参数将其转换为 tibble 来选择列名称 - 得益于 tidyr 魔法,它也可以在
mutate()
下工作:

library(tidyverse)

df <-
  data.frame(strings = c('a_b_c', 'ab_cd_ef', 'abc_def_ghi'))

df %>%
  mutate(stringr::str_match(strings, '([a-z]+)_([a-z]+)_([a-z]+)') %>%
         as_tibble(.name_repair = ~ c("matched", "prefix", "midfix", "suffix")))
      strings     matched prefix midfix suffix
1       a_b_c       a_b_c      a      b      c
2    ab_cd_ef    ab_cd_ef     ab     cd     ef
3 abc_def_ghi abc_def_ghi    abc    def    ghi

如果您想丢弃

matched
列(因为在此特定示例中它不会带来任何关于
strings
的附加信息),您可以在最后的管道步骤中执行此操作,例如
%>% select(-matched)
,在
mutate()
内部或外部,随您喜欢。


0
投票

我们可以使用

cSplit

library(splitstackshape)
cSplit(df, "strings", "_", drop = FALSE)

或使用

separate
 中的 
tidyr

library(tidyr)
library(stringr)
df %>%
    separate(strings, into = str_c('string_', 1:3), remove = FALSE)
© www.soinside.com 2019 - 2024. All rights reserved.