我有以下字符:
endvotes <- "Yes106No85EH2NT6ES0P1"
我希望data.frame
看起来像这样
Yes No EH NT ES P
106 85 2 6 0 1
我知道如何拆分其中的每一个,例如:
yes <- unlist(str_split(end_votes, "\\No"))[1]
yes <- as.integer(unlist(str_split(yes, "Yes"))[2])
yes
[1] 106
我猜一种可能性是按位置分割,但数字(一位,两位或三位)并不总是相同,因此我想分开答案(是,不,等等)。当然,我可以为每个答案(如上所述)做到这一点,但我确信有更优雅的方式。 谁能告诉我这是如何做得很好的? 感谢
答案 0 :(得分:3)
endvotes <- "Yes106No85EH2NT6ES0P1"
names <- strsplit(endvotes, "[[:digit:]]+")[[1]]
numbers <- strsplit(endvotes, "[[:alpha:]]+")[[1]][-1]
setNames(as.data.frame(t(as.numeric(numbers))), names)
# Yes No EH NT ES P
#1 106 85 2 6 0 1
答案 1 :(得分:3)
根本不需要使用正则表达式。从stringi
包中尝试这个函数,它按字符类(如数字,标点符号)分割字符向量:
require(stringi)
stri_split_charclass(str=endvotes,"\\p{N}",omit_empty=T)[[1]]
## [1] "Yes" "No" "EH" "NT" "ES" "P"
stri_split_charclass(str=endvotes,"\\p{L}",omit_empty=T)[[1]]
## [1] "106" "85" "2" "6" "0" "1"
str
只是向量,\p{N}
和\p{L}
是您要分割的类(N表示数字,L表示字母)。 omit_empty
删除&#34;&#34; - 空字符串。
答案 2 :(得分:2)
你可以使用像这样的正则表达式,每个匹配将在第一个捕获组中包含文本,值为第二个:
([a-zA-Z]+)([0-9]+)
基本上,这会选择一串字母,后跟一串数字。括号是捕获组,可以让您轻松检索所需的值。
请参阅Demo here
答案 3 :(得分:2)
你也可以试试regex
..
strsplit(endvotes, split = "(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])", perl = T)
## [[1]]
## [1] "Yes" "106" "No" "85" "EH" "2" "NT" "6" "ES" "0" "P" "1"
##
获得所需的格式
S <- strsplit(endvotes, split = "(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])", perl = T)[[1]]
res <- data.frame(t(S[seq_along(S)%%2 == 0]))
names(res) <- t(S[seq_along(S)%%2 == 1])
res
## Yes No EH NT ES P
## 1 106 85 2 6 0 1
或
res <- data.frame(t(regmatches(endvotes, gregexpr("[0-9]+", endvotes))[[1]]))
names(res) <- t(regmatches(endvotes, gregexpr("[A-Za-z]+", endvotes))[[1]])
res
## Yes No EH NT ES P
## 1 106 85 2 6 0 1