【问题标题】:Problem using dplyr on tibbles with vector elements [list columns]在带有矢量元素的小标题上使用 dplyr 时出现问题 [列出列]
【发布时间】:2019-03-03 18:33:48
【问题描述】:

我在使用 dplyr 和 stringr 函数(特别是 str_split())进行文本处理时遇到了一些问题。我想我误解了在处理向量/列表元素时如何正确使用 dplyr 的一些非常基本的东西。

这是一个小标题,df...

library(tidyverse)

df <- tribble(
  ~item, ~phrase,
  "one",   "romeo and juliet",
  "two",   "laurel and hardy",
  "three", "apples and oranges and pears and peaches"
)

现在我创建一个新列 splitPhrase,方法是在其中一个列上使用“and”作为分隔符执行 str_split() .

df <- df %>%
      mutate(splitPhrase = str_split(phrase,"and")) 

在 RStudio 中我看到了这个...

在控制台中,我看到我的新列 splitPhrase 实际上是由列表组成的……但在 Rstudio 显示中看起来是正确的,对吧?

df
#> # A tibble: 3 x 3
#>   item  phrase                                   splitPhrase
#>   <chr> <chr>                                    <list>     
#> 1 one   romeo and juliet                         <chr [2]>  
#> 2 two   laurel and hardy                         <chr [2]>  
#> 3 three apples and oranges and pears and peaches <chr [4]>

我最终想要做的是提取每个 splitPhrase 的 last。换句话说,我想达到这个...

问题是我看不到如何只抓取每个 splitPhrase 中的最后一个元素。如果它只是一个向量,我可以做这样的事情......

#> last( c("a","b","c") )
#[1] "c"
#> 

但这在 tibble 中不起作用,其他想到的东西也不起作用:

df <- df %>% 
       mutate(lastThing = last(splitPhrase))
# Error in mutate_impl(.data, dots) : 
#   Column `lastThing` must be length 3 (the number of rows) or one, not 4

df <- df %>% group_by(splitPhrase) %>%
  mutate(lastThing = last(splitPhrase))
# Error in grouped_df_impl(data, unname(vars), drop) : 
#  Column `splitPhrase` can't be used as a grouping variable because it's a list

所以,我认为我“没有得到”如何使用 table/tibble 列中元素内的向量。这似乎与在我的示例中它实际上是一个向量列表这一事实有关。

这里有什么特别的功能可以帮助我,或者有更好的方法来解决这个问题吗?

reprex package (v0.2.1) 于 2018 年 9 月 27 日创建

【问题讨论】:

    标签: r dplyr stringr tibble


    【解决方案1】:

    “splitPhrase”列是list,因此我们循环通过list 来获取元素

    library(tidyverse)
    df %>% 
       mutate(splitPhrase = str_split(phrase,"\\s*and\\s*"),
              Last = map_chr(splitPhrase, last)) %>%
       select(item, Last)
    

    但是,它可以通过多种方式完成。使用separate_rows,展开列,然后得到last元素按'item'分组

    df %>% 
      separate_rows(phrase,sep = " and ") %>% 
      group_by(item) %>% 
      summarise(Last = last(phrase))
    

    【讨论】:

    • 谢谢!所以“列表列”的显示与 RStudio 预览选项卡中的常规列没有什么不同?
    • @Angelo 如果您查看控制台输出,它会显示类型为list
    • 我认为我的根本误解在于“列表列”的概念。你的回答解决了我的问题!还发现这对背景很有用:rstudio.com/resources/videos/how-to-work-with-list-columns
    【解决方案2】:

    没有测试效率,但我们也可以使用正则表达式提取最后一个“and”之后的字符串段:

    sub:

    library(dplyr)
    df %>%
      mutate(lastThing = sub("^.*and\\s", "", phrase)) %>%
      select(-phrase)
    

    str_extract:

    library(stringr)
    df %>%
      mutate(lastThing = str_extract(phrase, "(?<=and\\s)\\w+$")) %>%
      select(-phrase)
    

    extract:

    library(tidyr)
    df %>%
      extract(phrase, "lastThing", "^.*and\\s(\\w+)")
    

    输出:

    # A tibble: 3 x 2
      item  lastThing
      <chr> <chr>    
    1 one   juliet   
    2 two   hardy    
    3 three peaches
    

    【讨论】:

    • 谢谢!我通常会使用带有 str_extract() 的正则表达式,这是我的第一选择!但我必须做一个最小的例子来展示我在“列表列”中遇到的核心问题
    猜你喜欢
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 2010-12-02
    • 2015-05-04
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多