我有一个如下数据框:
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中找到的第三个字符串解析?
在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
这是一个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
你可以使用str_split
包装的stringr
-
> library(stringr)
> library(data.table)
> setDT(dt)[,Col3:=sapply(Col2,function(x) unlist(str_split(x,"!!"))[3])]
输出 -
> dt
Col1 Col2 Col3
1: A 5!5!!6!!3!!m 3
2: B 7_8!!6!!7!!t 7
注意 - 您可以在position
中将3rd
从nth
更改为function
。
我们可以使用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))