owe*_*n88 5 regex r vector pattern-matching
我有一个矢量
vec <- c("ab", "#4", "gw", "#29", "mp", "jq", "#35", "ez")
Run Code Online (Sandbox Code Playgroud)
它通常遵循两个不同字符串序列之间交替的模式(第一个序列全部是字母顺序,第二个序列是数字,符号为#).
但是有些情况下没有出现#term:所以在上面mp和之间jq,然后再次出现ez.我想定义一个用字符串"填补空白"的函数#,这样我就可以输出:
[1] "ab" "#4" "gw" "#29" "mp" "#" "jq" "#35" "ez" "#"
Run Code Online (Sandbox Code Playgroud)
然后我将转换为数据框
V1 V2
1 ab #4
2 gw #29
3 mp #
4 jq #35
5 ez #
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的尝试相当笨重,依赖于遍历向量并填补空白.我有兴趣看到更优雅的解决方案.
我的解决方案
greplSpace <- function(pattern, replacement, x){
j <- 1
while( j < length(x) ){
if(grepl(pattern, x[j+1]) ){
j <- j+2
} else {
x <- c( x[1:j], replacement, x[(j+1):length(x)] )
j <- j+2
}
}
if( ! grepl(pattern, tail(x,1) ) ){ x <- c(x, replacement) }
return(x)
}
library(magrittr)
vec <- c("ab", "#4", "gw", "#29", "mp", "jq", "#35", "ez")
vec %>% greplSpace("#", "#", . ) %>%
matrix(ncol = 2, byrow = TRUE) %>%
as.data.frame
Run Code Online (Sandbox Code Playgroud)
从您的开始vec,我们可以直接使用dplyr,tidyr和stringr中的一些函数创建您期望的数据框.
library(dplyr)
library(tidyr)
library(stringr)
vec <- c("ab", "#4", "gw", "#29", "mp", "jq", "#35", "ez")
dat <- data_frame(Value = vec)
dat2 <- dat %>%
mutate(String = !str_detect(vec, "#"),
Key = ifelse(String, "V1", "V2"),
Row = cumsum(String)) %>%
select(-String) %>%
spread(Key, Value, fill = "#") %>%
select(-Row)
dat2
# # A tibble: 5 x 2
# V1 V2
# <chr> <chr>
# 1 ab #4
# 2 gw #29
# 3 mp #
# 4 jq #35
# 5 ez #
Run Code Online (Sandbox Code Playgroud)