我有一个字符向量:
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
列答案 0 :(得分:2)
这可以解决您的问题:
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次或更多次(带有*),而不是要求-
。 答案 1 :(得分:1)
这很微妙,因为strsplit(s, '%[(-)]%')
会丢弃您的分割模式,这对于'/'来说是可以的,但对于捕获百分号之间的中间字符而言是可以的。如果您保证右百分比后有空格,则可以执行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"
与此相关的轻微问题是衣衫agged的;最后一行没有符号。
由于在您的情况下,可以安全地假设只发生在行尾,因此最简单的方法是添加'%$%'行尾字符(注意尾随空格),然后映射$
- >以后不适用。