dplyr mutate +不公开问题

时间:2018-12-12 08:25:40

标签: r dplyr

我正在尝试提取数据框中的部分字符。

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]

所以我将其应用于mutate(dplyr):

t<-d %>% mutate(new1=(unlist(str_split(a,"_"))[2])) 

但是在所有情况下结果都是“ bb”。我做错了什么?

4 个答案:

答案 0 :(得分:1)

完成时

d %>% mutate(new1=(unlist(str_split(a,"_"))[2]))

它通过a中的str_split列。所以这等同于

unlist(str_split(d$a, "_"))
#[1] "aa"  "bb"  "cc"  "ddd" "eee" "fff" "sss" "rrr" "eee"

现在,当您对其进行子集化并获取其给出的第二个元素

unlist(str_split(d$a, "_"))[2]
#[1] "bb"

因此,该值将分配给所有案例。


要解决此问题,您可以添加操作rowwise以获得所需的输出,因为它将分别为a中的每一行传递str_split的值。

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

显然,您还可以使用sapplystrsplit

使用base R选项
sapply(strsplit(as.character(d$a), "_"), "[[", 2)
#[1] "bb"  "eee" "rrr"

答案 1 :(得分:0)

<application>

希望这行得通

答案 2 :(得分:0)

也许是开始使用(高度可定制的)正则表达式的好借口:

d[["new"]] <- gsub(".*_(.*)_.*", "\\1", d[["a"]])
d
            a new
1    aa_bb_cc  bb
2 ddd_eee_fff eee
3 sss_rrr_eee rrr

答案 3 :(得分:0)

我们可以使用for( itm in res[0]){ r1 += res[0][itm] ; } for( itm in res[1]){ r2 += res[1][itm] ; }......... <p> r1 <p> <p> r2 <p> .....

str_extract

或与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