将两个子模式上的字符串拆分为 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>
备注:
/
分点:我想把x / y
分成x
部分和y
部分。
- 第二次拆分
%*%
应该进入符号列 z
,但没有 %
;
我尝试了各种版本的 strsplit
但没有成功:
trimws(unlist(strsplit(s, "[/(%*%)]")))
[1] "0" "0" "" "" "1" "1" "-" "2" "2" "" "" "3" "3"
问题:
-
没有被 (%*%)
捕获,为什么?
- 我里面有空字符串部分,为什么?
- 我不知道如何将
split
存储到 z
列中
这解决了您的问题:
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 创建
致您的第一期:
%*%
不捕获 -
因为您要求正则表达式重复 %
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 稍后。
我有一个字符向量:
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>
备注:
/
分点:我想把x / y
分成x
部分和y
部分。- 第二次拆分
%*%
应该进入符号列z
,但没有%
;
我尝试了各种版本的 strsplit
但没有成功:
trimws(unlist(strsplit(s, "[/(%*%)]")))
[1] "0" "0" "" "" "1" "1" "-" "2" "2" "" "" "3" "3"
问题:
-
没有被(%*%)
捕获,为什么?- 我里面有空字符串部分,为什么?
- 我不知道如何将
split
存储到z
列中
这解决了您的问题:
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 创建致您的第一期:
%*%
不捕获-
因为您要求正则表达式重复%
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 稍后。