R中的第n个分隔符解析

时间:2019-04-22 17:00:52

标签: r strsplit

我有一个如下数据框:

Col1    Col2
   A    5!5!!6!!3!!m
   B    7_8!!6!!7!!t

structure(list(Col1 = c("A", "B"), Col2 = c("5!5!!6!!3!!m", "7_8!!6!!7!!t" )), class = "data.frame", row.names = c(NA, -2L))

如何创建一个新列以提取在Col2中找到的字符串的第3个解析?

在SQL中,我正在使用SPLIT_PART函数:

SPLIT_PART(Col2, '!!', 3)

我正在寻找R中的等效函数。

预期输出:

Col1            Col2    Col3
   A    5!5!!6!!3!!m       3
   B    7_8!!6!!7!!t       7

3 个答案:

答案 0 :(得分:1)

我们可以使用str_extract提取数字

library(stringr)
df1 %>%
  mutate(Col3 = as.numeric(str_extract(Col2, "\\d+(?=!![a-z]+$)")))
#  Col1         Col2 Col3
#1    A 5!5!!6!!3!!m    3
#2    B 7_8!!6!!7!!t    7

如果我们按位置需要它,那么

df1$Col3 <- as.numeric(sapply(strsplit(df1$Col2, "!!", fixed = TRUE), `[`, 3))
df1$Col3
#[1] 3 7

或者使用gsubfn创建位置标识符,然后提取之前的数字

library(gsubfn)
p <- proto(fun = function(this, x)  if(count == 3) paste0(";", x))
as.numeric(str_extract(gsubfn("(!!)", p, df1$Col2), "\\d+(?=;)"))
#[1] 3 7

数据

df1 <- structure(list(Col1 = c("A", "B"), Col2 = c("5!5!!6!!3!!m", "7_8!!6!!7!!t"
 )), class = "data.frame", row.names = c(NA, -2L))

答案 1 :(得分:1)

您可以使用RegExp_Replace(col, 'valuable data|other data|there is nothing', '', 1, 0, 'i') 软件包中的str_split-

stringr

输出-

> library(stringr)
> library(data.table)
> setDT(dt)[,Col3:=sapply(Col2,function(x) unlist(str_split(x,"!!"))[3])]

注意-您可以将{{1}中的> dt Col1 Col2 Col3 1: A 5!5!!6!!3!!m 3 2: B 7_8!!6!!7!!t 7 position更改为3rd

答案 2 :(得分:1)

这是一个tidyverse选项,尽管核心在功能上与Rushabh's data.table based answer相同。

当给定simplify=T参数时,stringr::str_split将输出一个矩阵,每个匹配项都在一个列中。您可以从中将所需的列作为子集来提取所需的位置:

library(tidyverse)

df1 %>%
    mutate(Col3 = str_split(Col2, pattern = '!!', simplify=T)[,3])

  Col1         Col2 Col3
1    A 5!5!!6!!3!!m  5!5
2    B 7_8!!6!!7!!t  7_8

df1 %>%
    mutate(Col3 = str_split(Col2, pattern = '!!', simplify=T)[,2])

  Col1         Col2 Col3
1    A 5!5!!6!!3!!m    6
2    B 7_8!!6!!7!!t    6

df1 %>%
  mutate(Col3 = str_split(Col2, pattern = '!!', simplify=T)[,1])

  Col1         Col2 Col3
1    A 5!5!!6!!3!!m  5!5
2    B 7_8!!6!!7!!t  7_8