【问题标题】:dplyr mutate + unlist issuedplyr mutate + unlist 问题
【发布时间】:2018-12-12 08:25:40
【问题描述】:

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

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”。我做错了什么?

【问题讨论】:

  • 总是很有趣的函数word,即stringr::word(d$a, 2, sep = '_')

标签: r dplyr


【解决方案1】:

当你这样做时

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

它通过str_split 中的a 列。所以这相当于

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

显然您也可以使用sapplystrsplit 来使用base R 选项

sapply(strsplit(as.character(d$a), "_"), "[[", 2)
#[1] "bb"  "eee" "rrr"

【讨论】:

    【解决方案2】:
    d1 <- as.data.frame(unlist(str_split_fixed(d$a,"_", n =3)))
    

    希望这行得通

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案4】:

        我们可以使用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

        d$new <- read.table(text = as.character(d$a), header = FALSE, sep="_")[,2]
        

        【讨论】:

          猜你喜欢
          • 2017-08-08
          • 1970-01-01
          • 2015-05-02
          • 2016-08-01
          • 2018-03-16
          • 2016-01-28
          • 2017-05-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多