R-查找和;从右边提取字符串
我有这个向量:R-查找和;从右边提取字符串,r,tidyverse,R,Tidyverse,我有这个向量: data <- structure(1:5, .Label = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8", "prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5"), class = "factor") V1 1 &quo
data <- structure(1:5, .Label = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8",
"prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5"), class = "factor")
V1
1 "AVE_prQD_AFR_p10"
2 "PER_prVD_DSR_p9"
3 "PA_prS_X_AR_p8"
4 "prAV_AES_p7"
5 "prGR_AXXR_p6"
从上面的示例可以推断,字符串的最后一部分将始终以\uu
开头,然后是p
、f
或0
,然后以1到99之间的数字结束字符串(0除外):
数字后面永远不会有任何东西。因此,整个字符串以我需要的字符串结尾。因此,我正在寻找一个解决方案,试图从右侧搜索
,但未成功
另外,我需要在以下条件下转换该字符串:
- 如果字符串有
,则将该数字乘以p
-1
- 如果字符串有
,则数字为正数f
- 如果字符串是
,则将其指定为\u 0
0
\uuu
和数字0到9的情况下工作
function(some_vector_string){
result <- stringr::str_sub(some_vector_string, -2,-2) %>%
{ifelse(. == "p",
as.numeric(stringr::str_sub(some_vector_string, -1,-1))*-1,
ifelse(. == "f",
as.numeric(stringr::str_sub(some_vector_string, -1,-1))*1,
ifelse(.=="_", 0, -100)))}
return(result)
}
函数(一些向量字符串){
结果%
{ifelse(.==“p”,
as.numeric(stringr::str_sub(某些向量_字符串,-1,-1))*-1,
ifelse(.=“f”,
as.numeric(stringr::str_sub(某些向量_字符串,-1,-1))*1,
ifelse(.==”,0,-100))}
返回(结果)
}
我尝试使用REBS,结果如下:
library(tidyverse)
library(rebus)
library(stringr)
data <- structure(1:5, .Label = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8",
"prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5"), class = "factor")
#rebus END regex lets you narrow the search to the last part of the string
chars <-
str_extract(data , rebus::or(ANY_CHAR %R% one_or_more(DGT) %R% END, '0' %R% END))
##fabricate the conditions
#map_dbl is also an option to avoid returning a list
numbers <-
map(chars, ~
if(str_sub(.x,1 ,1) == 'p'){
as.numeric(str_extract(.x, one_or_more(DGT))) * -1
} else{
if (str_sub(.x,1 ,1) == 'f'){
as.numeric(str_extract(.x, one_or_more(DGT)))
} else {
0
}
})
print(numbers)
``
库(tidyverse)
图书馆(REBS)
图书馆(stringr)
数据我尝试了REBS,结果如下:
library(tidyverse)
library(rebus)
library(stringr)
data <- structure(1:5, .Label = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8",
"prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5"), class = "factor")
#rebus END regex lets you narrow the search to the last part of the string
chars <-
str_extract(data , rebus::or(ANY_CHAR %R% one_or_more(DGT) %R% END, '0' %R% END))
##fabricate the conditions
#map_dbl is also an option to avoid returning a list
numbers <-
map(chars, ~
if(str_sub(.x,1 ,1) == 'p'){
as.numeric(str_extract(.x, one_or_more(DGT))) * -1
} else{
if (str_sub(.x,1 ,1) == 'f'){
as.numeric(str_extract(.x, one_or_more(DGT)))
} else {
0
}
})
print(numbers)
``
库(tidyverse)
图书馆(REBS)
图书馆(stringr)
数据在baseR
中,类似于:
a <- sapply(strsplit(as.character(data), "_"), function(x) rev(x)[1])
ifelse(startsWith(a, "0"), 0, c(-1, 1)[startsWith("p", a) + 1] * as.numeric(gsub("\\D*", "", a)))
[1] -10 -9 -8 -7 -6
这与ungreedy(?
)相反,ungreedy不尝试尽可能匹配:
str_remove("A_B_C_D", ".*?_")
[1] "B_C_D"
purrr::map\u dbl
此函数迭代列表或原子向量,并输出double类型的原子向量,因此为\u dbl
~
是一种lambda/purrr风格的语法。在R
4.1.0之前,它都是用baseR
编写的:function(x)n[substr(x,1,1)]*parse_number(x)
。它只是一种更简洁、更容易阅读、不太冗长的匿名函数应用方式(即未指定名称的函数)。这是tidyverse中常见的语法样式。此处,函数的x
参数被点符号
替换
n[substr(,1,1)]*解析编号(。
substr(,1,1)
获取解析字符串的第一个字符:
substr("f20", 1,1 )
[1] "f"
然后它查找命名向量n
中的第一个字符,以返回您在问题中指定的值,当字母为“f”
时,该值为:
readr::parse_number
从字符串中提取所有数字并将其作为数字返回:
readr::parse_number("f20")
[1] 20
这两个值相乘,并作为双原子向量输出中的元素返回
注意:当后缀为“0”
时,此操作有效,因为此操作的结果为0*0
:
substr("0",1 ,1)
[1] "0"
n["0"]
0
0
parse_number("0")
[1] 0
n[substr("0", 1, 1)] * parse_number("0")
0
0
您会注意到,从技术上讲,此输出是一个命名向量,名称为“0”
,值为0
;但是,这是由baseR
中的map\u dbl
强制为双向量的,类似于:
a <- sapply(strsplit(as.character(data), "_"), function(x) rev(x)[1])
ifelse(startsWith(a, "0"), 0, c(-1, 1)[startsWith("p", a) + 1] * as.numeric(gsub("\\D*", "", a)))
[1] -10 -9 -8 -7 -6
这与ungreedy(?
)相反,ungreedy不尝试尽可能匹配:
str_remove("A_B_C_D", ".*?_")
[1] "B_C_D"
purrr::map\u dbl
此函数迭代列表或原子向量,并输出double类型的原子向量,因此为\u dbl
~
是一种lambda/purrr风格的语法。在R
4.1.0之前,它都是用baseR
编写的:function(x)n[substr(x,1,1)]*parse_number(x)
。它只是一种更简洁、更容易阅读、不太冗长的匿名函数应用方式(即未指定名称的函数)。这是tidyverse中常见的语法样式。此处,函数的x
参数被点符号
替换
n[substr(,1,1)]*解析编号(。
substr(,1,1)
获取解析字符串的第一个字符:
substr("f20", 1,1 )
[1] "f"
然后它查找命名向量n
中的第一个字符,以返回您在问题中指定的值,当字母为“f”
时,该值为:
readr::parse_number
从字符串中提取所有数字并将其作为数字返回:
readr::parse_number("f20")
[1] 20
这两个值相乘,并作为双原子向量输出中的元素返回
注意:当后缀为“0”
时,此操作有效,因为此操作的结果为0*0
:
substr("0",1 ,1)
[1] "0"
n["0"]
0
0
parse_number("0")
[1] 0
n[substr("0", 1, 1)] * parse_number("0")
0
0
您会注意到,从技术上讲,此输出是一个命名向量,名称为“0”
,值为0
;但是,这是由map\u dbl
数据强制为双向量的:
data <- data.frame(V1 = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8",
"prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5",
"AVE_prQD_AFR_f10", "PER_prVD_DSR_f9", "PA_prSX_AR_f8",
"prAV_AES_f7", "prGR_AXXR_f6", "prQW_AWAR_f5",
"AVE_prQD_AFR_0", "PER_prVD_DSR_0", "PA_prSX_AR_0",
"prAV_AES_0", "prGR_AXXR_0", "prQW_AWAR_0"))
data %>%
tidyr::extract(V1, c("V2", "V3"), "([[:alnum:]_]+)_([[:alnum:]]+)$", remove = FALSE) %>%
mutate(V4 = readr::parse_number(V3),
v5 = case_when(stringr::str_detect(V3, "p") ~ V4*-1,
TRUE ~ V4))
方法2
或者,与将字符串拆分为2(如方法1所示)不同,我们可以只提取感兴趣的部分并从中开始工作
data %>%
mutate(V2 = stringr::str_extract(V1, "[pf]?\\d{1,2}$"),
V3 = readr::parse_number(V2),
v4 = case_when(stringr::str_detect(V2, "p") ~ V3*-1,
TRUE ~ V3))
数据:
data <- data.frame(V1 = c("AVE_prQD_AFR_p10", "PER_prVD_DSR_p9", "PA_prSX_AR_p8",
"prAV_AES_p7", "prGR_AXXR_p6", "prQW_AWAR_p5",
"AVE_prQD_AFR_f10", "PER_prVD_DSR_f9", "PA_prSX_AR_f8",
"prAV_AES_f7", "prGR_AXXR_f6", "prQW_AWAR_f5",
"AVE_prQD_AFR_0", "PER_prVD_DSR_0", "PA_prSX_AR_0",
"prAV_AES_0", "prGR_AXXR_0", "prQW_AWAR_0"))
data %>%
tidyr::extract(V1, c("V2", "V3"), "([[:alnum:]_]+)_([[:alnum:]]+)$", remove = FALSE) %>%
mutate(V4 = readr::parse_number(V3),
v5 = case_when(stringr::str_detect(V3, "p") ~ V4*-1,
TRUE ~ V4))
方法2
或者,与将字符串拆分为2(如方法1所示)不同,我们可以只提取感兴趣的部分并从中开始工作
data %>%
mutate(V2 = stringr::str_extract(V1, "[pf]?\\d{1,2}$"),
V3 = readr::parse_number(V2),
v4 = case_when(stringr::str_detect(V2, "p") ~ V3*-1,
TRUE ~ V3))
提取所有结束数字并与-1相乘的解决方案,如果它们以f开头(正数无论如何都可以,0没有符号):
库(tidyverse)
数据%
enframe(name=NULL,value=“V1”)%%>%#从矢量创建可编辑文件
mutate(want=as.numeric(str_extract(V1,\\d+$))))*if_else(str_detect(V1,\\f\\d+$)-1))
#想要
#
#1 AVE_prQD_AFR_p10 10
#每件2件9件
#第3页第8页
#4 prAV_AES_p7 7
#5 prGR_AXXR_p6 6
#6 prQW_AWAR_p5 5
#7 prQW_AWAR_0 0
#8 prQW_AWAR_f5-5
提取所有结尾数字并与-1相乘的解决方案,如果它们以f(正数)开头