У меня есть вектор символов:
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
s в столбце 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
Created on 2019-04-09 by the reprex package (v0.2.1)
К вашему первому выпуску:
%*%
не захватывает -
, потому что вы просите регулярное выражение повторить %
0 или более раз (со звездочкой *), но не запрашиваете -
.Это тонко, потому что 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"
Небольшая проблема с тем, что он рваный; последняя строка не имеет символа.
Поскольку в вашем случае кажется безопасным предположить, что это происходит только в конце строки, проще всего добавить символ конца строки '%$%' (обратите внимание на завершающий пробел), а затем сопоставить $
-> NA позже.
Обратите внимание, что
strsplit(s, '%[(-)]%')
отбрасывает ваши шаблоны разделения, что было бы нормально для '/', но не для захвата среднего символа между процентами. Если вы гарантируете наличие пробела после нужного процента, вы можете просто сделатьstrsplit(s, '% ')
; в противном случае вам понадобится регулярное выражение с утверждением правого просмотра для цифр. Проще и понятнее сделать два разбиения, сделать первое разбиение на правом проценте '%'.