将两个子模式上的字符串拆分为 data.frame

Split string on two subpatterns into data.frame

我有一个字符向量:

s <- "0 / 10 %(% 1 / 11 %-% 2 / 12 %)% 3 / 13"

目标是在 /%*% 上将其拆分为 (x,y) 点和 z 符号:

data.frame(x = c(0,1,2,3), y = c(10,11,12,13), z = c("(", "-", ")", NA),
           stringsAsFactors = FALSE)
  x  y    z
1 0 10    (
2 1 11    -
3 2 12    )
4 3 13 <NA>

备注:

我尝试了各种版本的 strsplit 但没有成功:

trimws(unlist(strsplit(s, "[/(%*%)]")))
[1] "0" "0" ""  ""  "1" "1" "-" "2" "2" ""  ""  "3" "3"

问题

这解决了您的问题:


str <- "0 / 10 %(% 1 / 11 %-% 2 / 12 %)% 3 / 13"

str_sub <- gsub("[%/]","",str) #sub all % and / with ""
str_split <- strsplit(str_sub,"\s+")[[1]] #split by whitespace
str_corr <- c(str_split,rep(NA,3-length(str_split) %% 3)) #correct length, fill the end with NAs

df <- as.data.frame(matrix(str_corr,ncol=3,byrow=TRUE)) #convert to data.frame via matrix
colnames(df) <- c("x","y","z") #set colnames

reprex package (v0.2.1)

于 2019-04-09 创建

致您的第一期:

  1. %*% 不捕获 - 因为您要求正则表达式重复 % 0 次或更多次(使用 *)但不要求 -.

这很微妙,因为 strsplit(s, '%[(-)]%') 丢弃了您的拆分模式,这对于 '/' 是可以的,但对于捕获百分比之间的中间字符则不行。如果你保证在正确的百分比之后有一个 space,你可以做 strsplit(s, '% ');否则,您将需要一个带有数字右前瞻断言的正则表达式。

做两次拆分更容易也更清晰:第一次拆分在“%”右百分比上:

s2 <- strsplit(s, '% ')[[1]]

"0 / 10 %(" "1 / 11 %-" "2 / 12 %)" "3 / 13"

现在您对“/”和左百分号字符进行第二次拆分:

> strsplit(s2, '[%/]')

[[1]]
[1] "0 "   " 10 " "("   

[[2]]
[1] "1 "   " 11 " "-"   

[[3]]
[1] "2 "   " 12 " ")"   

[[4]]
[1] "3 "  " 13"

这个有点破烂;最后一行没有符号。 因为在你的情况下,假设只发生在行尾似乎是安全的,最简单的kludge是添加一个'%$%'行尾字符(注意尾随space),然后映射$ -> NA 稍后。