【问题标题】:String splitting a dataframe with a vector as the pattern in R字符串将数据帧与向量作为 R 中的模式进行拆分
【发布时间】:2017-10-05 10:25:32
【问题描述】:

我有一个由多行组成的数据框,我想根据 R 中的向量元素(本质上以向量作为“模式”运行 strsplit)将每一行拆分为两个组件。

数据框(只有一列)看起来像这样:

     [,1]                
[1,] "apple please fuji" 
[2,] "pear help name"    
[3,] "banana me mango"   

而我的模式向量可能如下所示:v <- c("please", "help", "me")

如果可能,我希望我的 end 输出为:

  df$name             df$part1  df$split  df$part2   
 "apple please fuji" "apple"    "please"  "fuji" 
 "pear help name"    "pear"     "help"    "name" 
 "banana me mango"   "banana"   "me"      "mango"

对于能够基于向量隔离组件的中间步骤的任何帮助,我将不胜感激,但如果有更简单的方法将其放入数据框中,那就太好了!非常感谢!

【问题讨论】:

  • 如果第一行是"red apple please fuji" ,结果是c("red apple", "please", "fuji") ?
  • @zx8754,是的,这就是我所希望的!我只想隔离三个类别(无论单词数量如何):分割字符串之前,分割字符串和分割字符串之后。谢谢!

标签: r strsplit


【解决方案1】:

这是基础 R 中的两种方法。

从一个字符向量开始:

text <- c("apple please fuji", "pear help name", "banana me mango")

此外,所需的变量名称(为方便起见)

varNames <- c("name", "part1", "split", "part2")

使用regexecregmatches

您也可以将正则表达式与regmatches / regexec 组合使用来构建此数据集。

首先,使用 paste 从 v 构建一个正则表达式。

myRegex <- paste0("^(.*) +(", paste(v, collapse="|"), ") +(.*)$")
myRegex
[1] "^(.*)(please|help|me)(.*)$"

setNames(do.call(rbind.data.frame, regmatches(text, regexec(myRegex, text))), varNames)

返回和上面一样

               name  part1  split part2
1 apple please fuji  apple please  fuji
2    pear help name   pear   help  name
3   banana me mango banana     me mango

使用strsplitdo.call

首先,将每个元素按v分割

tmp <- do.call(strsplit, list(text, split=v))
tmp
[[1]]
[1] "apple " " fuji" 

[[2]]
[1] "pear " " name"

[[3]]
[1] "banana " " mango" 

现在,rbind.data.frame 这些,它会删除第二列,并返回一个 data.frame cbind 的 split 和 name 变量,然后添加带有 setNames 的名称。

setNames(cbind(text, do.call(rbind.data.frame, tmp), v)[c(1, 2, 4, 2)], varNames)

返回

               name   part1  split   part2
1 apple please fuji  apple  please  apple 
2    pear help name   pear    help   pear 
3   banana me mango banana      me banana 

【讨论】:

    【解决方案2】:

    此解决方案假定v 中的元素数等于数据框中的行数。您可以使用tidyr 包中的separate 创建part1part2

    library(tidyverse)
    df <- tibble(name = c("apple please fuji", "pear help name", "banana me mango"))
    v <- c("please", "help", "me")
    
    df %>% 
      separate(name, c("part1", "part2"), v, remove = FALSE) %>%
      add_column(split = v, .before = "part2")
    #> # A tibble: 3 x 4
    #>                name   part1  split  part2
    #>               <chr>   <chr>  <chr>  <chr>
    #> 1 apple please fuji  apple  please   fuji
    #> 2    pear help name   pear    help   name
    #> 3   banana me mango banana      me  mango
    

    如果您想尝试使用 v 中的 any 元素拆分每一行,那么您可以先尝试将 v 粘贴到单个模式中,然后再进行拆分。我认为这样的事情应该有效。

    library(tidyverse)
    library(stringr)
    p <- paste0("\\b(?:", paste(v, collapse = "|"), ")\\b")
    df %>% 
      separate(name, c("part1", "part2"), p, remove = FALSE) %>%
      mutate(split = str_extract(name, p)) %>%
      select(name, part1, split, part2)
    #> # A tibble: 3 x 4
    #>                name   part1  split  part2
    #>               <chr>   <chr>  <chr>  <chr>
    #> 1 apple please fuji  apple  please   fuji
    #> 2    pear help name   pear    help   name
    #> 3   banana me mango banana      me  mango
    

    【讨论】:

      【解决方案3】:
      # Creating creating the df
      name <- c("apple please fuji","pear help name","banana me mango")
      
      # as.data.frame
      df <- as.data.frame(name, stringsAsFactors = F)
      # Initialize empty data frame. 
      df_n <- data.frame()
      # Loop through the original rows of the df. 
      for(i in 1:nrow(df)){
        for(j in 1:nrow(df)){
          o <- strsplit(df$name, " ")[[i]][j]
        }
      }
      # rename and assign new df (df_n) changes to original df. 
      df$part1 <- df_n$V1
      df$part2 <- df_n$V2
      df$part3 <- df_n$V3
      
      print(df)
      

      【讨论】:

      • 谢谢! for 循环很慢,而且我的数据框大小很大,所以不幸的是这些对我不起作用。您对如何矢量化它有任何想法,也许使用应用?谢谢!
      猜你喜欢
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多