我正在尝试提取数据帧中的部分字符。
d<-data.frame(a=c("aa_bb_cc", "ddd_eee_fff", "sss_rrr_eee"))
我想在新专栏中加入"bb"、"eee"、"rrr"的部分。当使用以下结构时,效果良好:
unlist(str_split(d$a[1],"_"))[2]
unlist(str_split(d$a[2],"_"))[2]
所以我把它应用于突变(dplyr(:
t<-d %>% mutate(new1=(unlist(str_split(a,"_"))[2]))
但在所有情况下,结果都是"bb"。我做错了什么?
进行时
d %>% mutate(new1=(unlist(str_split(a,"_"))[2]))
它通过CCD_ 2中的CCD_。这相当于
unlist(str_split(d$a, "_"))
#[1] "aa" "bb" "cc" "ddd" "eee" "fff" "sss" "rrr" "eee"
现在,当你把它子集化,得到第二个元素时,它会给出
unlist(str_split(d$a, "_"))[2]
#[1] "bb"
因此,该值被分配给所有情况。
要解决此问题,您可以添加操作rowwise
以获得所需输出,因为它将分别为str_split
中的每一行传递a
的值。
library(tidyverse)
d %>%
rowwise() %>%
mutate(new1= unlist(str_split(a,"_"))[2])
# a new1
# <fct> <chr>
#1 aa_bb_cc bb
#2 ddd_eee_fff eee
#3 sss_rrr_eee rrr
或者另一个更安全的选项是使用separate
,并根据分隔符将字符串划分为不同的列,select
是相关的列
d %>%
separate(a, into = c("one", "two", "three"), sep = "_", remove = FALSE) %>%
select(a, two)
# a two
#1 aa_bb_cc bb
#2 ddd_eee_fff eee
#3 sss_rrr_eee rrr
显然,您也可以使用sapply
和strsplit
使用基本R选项
sapply(strsplit(as.character(d$a), "_"), "[[", 2)
#[1] "bb" "eee" "rrr"
d1 <- as.data.frame(unlist(str_split_fixed(d$a,"_", n =3)))
希望这能起作用
也许是开始使用(高度可定制(正则表达式的好借口:
d[["new"]] <- gsub(".*_(.*)_.*", "\1", d[["a"]])
d
a new
1 aa_bb_cc bb
2 ddd_eee_fff eee
3 sss_rrr_eee rrr
我们可以使用a
0
library(tidyverse)
d %>%
mutate(new = str_extract(a, "(?<=_)[^_]+"))
# a new
#1 aa_bb_cc bb
#2 ddd_eee_fff eee
#3 sss_rrr_eee rrr
或使用base R
d$new <- read.table(text = as.character(d$a), header = FALSE, sep="_")[,2]