我有一个包含字符串列的数据框,并希望将这些字符串的子字符串提取到新列中。
以下是一些示例代码和数据,显示我想在id
列中的最后一个下划线字符后面加上字符串,以便创建new_id
列。
id
列条目总是有2个下划线字符,它总是我想要的最终子字符串。
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])
我期待strsplit依次对每一行采取行动。
但是,new_id
列每行只包含ABC
,而我希望第1行为ABC
,第2行为NHYK
。你知道为什么会这样吗?失败了,如何实现我的目标?
答案 0 :(得分:16)
您可以使用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
正则表达式说,匹配不是 +
的一个或多个(_
)字符(否定[^ ]
),然后结束字符串($
)。
答案 1 :(得分:9)
没有正则表达式并保持tidyverse
样式的替代方法是使用tidyr::separate()
。请注意,默认情况下会删除输入列(remove=FALSE
以防止它)。
## 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
答案 2 :(得分:8)
Use dplyr::rowwise
:
df %>% dplyr::rowwise() %>% dplyr::mutate(new_id = strsplit(id, split="_")[[1]][3])
Further alternatives are discussed here:
http://www.expressivecode.org/2014/12/17/mutating-using-functions-in-dplyr/
答案 3 :(得分:1)
这是使用strsplit
以一般方式执行您正在寻找的内容的一种方法。
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
答案 4 :(得分:1)
这可以通过指定 str_split
参数使用 simplify
来完成。
Simplify 取消列出拆分字符串并允许使用索引选择元素。在这种总是有 2 个“_”的情况下,我们总是可以取第三个元素。
# Create df
df = data.frame( id = I(c("abcd_123_ABC","abc_5234_NHYK")), x = c(1.0,2.0) )
# Create new_id using dplyr only
df <- df %>%
mutate(new_id = str_split(id, "_", simplify = TRUE)[ , 3])