如何正确组合 mutate 和 str_match?
How to combine mutate and str_match correctly?
假设我想将字符串列拆分为单独的列。为此,我使用了 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
我们可以使用cSplit
library(splitstackshape)
cSplit(df, "strings", "_", drop = FALSE)
或使用 tidyr
中的 separate
library(tidyr)
library(stringr)
df %>%
separate(strings, into = str_c('string_', 1:3), remove = FALSE)
以最通用的形式回答原始问题: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
列(因为在这个特定示例中它不会带来任何附加信息 w.r.t。strings
),您可以在最后的流水线步骤,例如%>% select(-matched)
,在 mutate()
的内部或外部都可以。
假设我想将字符串列拆分为单独的列。为此,我使用了 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
我们可以使用cSplit
library(splitstackshape)
cSplit(df, "strings", "_", drop = FALSE)
或使用 tidyr
separate
library(tidyr)
library(stringr)
df %>%
separate(strings, into = str_c('string_', 1:3), remove = FALSE)
以最通用的形式回答原始问题: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
列(因为在这个特定示例中它不会带来任何附加信息 w.r.t。strings
),您可以在最后的流水线步骤,例如%>% select(-matched)
,在 mutate()
的内部或外部都可以。