我有一个包含文本字符串的对象:
x <- "xxyyxyxy"
Run Code Online (Sandbox Code Playgroud)
我想把它拆分成一个向量,每个元素包含两个字母:
[1] "xx" "yy" "xy" "xy"
Run Code Online (Sandbox Code Playgroud)
看起来strsplit
应该是我的票,但由于我没有正则表达式foo,我无法弄清楚如何使这个功能将字符串按照我想要的方式切成块.我该怎么做?
Sha*_*ane 58
使用substring
是最好的方法:
substring(x, seq(1, nchar(x), 2), seq(2, nchar(x), 2))
Run Code Online (Sandbox Code Playgroud)
但这是plyr的解决方案:
library("plyr")
laply(seq(1, nchar(x), 2), function(i) substr(x, i, i+1))
Run Code Online (Sandbox Code Playgroud)
GSe*_*See 24
这是一个快速的解决方案,将字符串拆分为字符,然后将偶数元素和奇数元素粘贴在一起.
x <- "xxyyxyxy"
sst <- strsplit(x, "")[[1]]
paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)])
Run Code Online (Sandbox Code Playgroud)
基准设置:
library(microbenchmark)
GSee <- function(x) {
sst <- strsplit(x, "")[[1]]
paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)])
}
Shane1 <- function(x) {
substring(x, seq(1,nchar(x),2), seq(2,nchar(x),2))
}
library("plyr")
Shane2 <- function(x) {
laply(seq(1,nchar(x),2), function(i) substr(x, i, i+1))
}
seth <- function(x) {
strsplit(gsub("([[:alnum:]]{2})", "\\1 ", x), " ")[[1]]
}
geoffjentry <- function(x) {
idx <- 1:nchar(x)
odds <- idx[(idx %% 2) == 1]
evens <- idx[(idx %% 2) == 0]
substring(x, odds, evens)
}
drewconway <- function(x) {
c<-strsplit(x,"")[[1]]
sapply(seq(2,nchar(x),by=2),function(y) paste(c[y-1],c[y],sep=""))
}
KenWilliams <- function(x) {
n <- 2
sapply(seq(1,nchar(x),by=n), function(xx) substr(x, xx, xx+n-1))
}
RichardScriven <- function(x) {
regmatches(x, gregexpr("(.{2})", x))[[1]]
}
Run Code Online (Sandbox Code Playgroud)
基准1:
x <- "xxyyxyxy"
microbenchmark(
GSee(x),
Shane1(x),
Shane2(x),
seth(x),
geoffjentry(x),
drewconway(x),
KenWilliams(x),
RichardScriven(x)
)
# Unit: microseconds
# expr min lq median uq max neval
# GSee(x) 8.032 12.7460 13.4800 14.1430 17.600 100
# Shane1(x) 74.520 80.0025 84.8210 88.1385 102.246 100
# Shane2(x) 1271.156 1288.7185 1316.6205 1358.5220 3839.300 100
# seth(x) 36.318 43.3710 45.3270 47.5960 67.536 100
# geoffjentry(x) 9.150 13.5500 15.3655 16.3080 41.066 100
# drewconway(x) 92.329 98.1255 102.2115 105.6335 115.027 100
# KenWilliams(x) 77.802 83.0395 87.4400 92.1540 163.705 100
# RichardScriven(x) 55.034 63.1360 65.7545 68.4785 108.043 100
Run Code Online (Sandbox Code Playgroud)
基准2:
现在,随着更大的数据.
x <- paste(sample(c("xx", "yy", "xy"), 1e5, replace=TRUE), collapse="")
microbenchmark(
GSee(x),
Shane1(x),
Shane2(x),
seth(x),
geoffjentry(x),
drewconway(x),
KenWilliams(x),
RichardScriven(x),
times=3
)
# Unit: milliseconds
# expr min lq median uq max neval
# GSee(x) 29.029226 31.3162690 33.603312 35.7046155 37.805919 3
# Shane1(x) 11754.522290 11866.0042600 11977.486230 12065.3277955 12153.169361 3
# Shane2(x) 13246.723591 13279.2927180 13311.861845 13371.2202695 13430.578694 3
# seth(x) 86.668439 89.6322615 92.596084 92.8162885 93.036493 3
# geoffjentry(x) 11670.845728 11681.3830375 11691.920347 11965.3890110 12238.857675 3
# drewconway(x) 384.863713 438.7293075 492.594902 515.5538020 538.512702 3
# KenWilliams(x) 12213.514508 12277.5285215 12341.542535 12403.2315015 12464.920468 3
# RichardScriven(x) 11549.934241 11730.5723030 11911.210365 11989.4930080 12067.775651 3
Run Code Online (Sandbox Code Playgroud)
小智 20
怎么样
strsplit(gsub("([[:alnum:]]{2})", "\\1 ", x), " ")[[1]]
Run Code Online (Sandbox Code Playgroud)
基本上,添加一个分隔符(此处为"")然后使用strsplit
geo*_*try 10
strsplit将会出现问题,看看像这样的正则表达式
strsplit(z, '[[:alnum:]]{2}')
Run Code Online (Sandbox Code Playgroud)
它将在正确的点分裂,但没有留下任何东西.
你可以使用子串和朋友
z <- 'xxyyxyxy'
idx <- 1:nchar(z)
odds <- idx[(idx %% 2) == 1]
evens <- idx[(idx %% 2) == 0]
substring(z, odds, evens)
Run Code Online (Sandbox Code Playgroud)
这是一种方法,但不使用regexen:
a <- "xxyyxyxy"
n <- 2
sapply(seq(1,nchar(a),by=n), function(x) substr(a, x, x+n-1))
Run Code Online (Sandbox Code Playgroud)
完全黑客,JD,但它完成了它
x <- "xxyyxyxy"
c<-strsplit(x,"")[[1]]
sapply(seq(2,nchar(x),by=2),function(y) paste(c[y-1],c[y],sep=""))
[1] "xx" "yy" "xy" "xy"
Run Code Online (Sandbox Code Playgroud)
小智 5
注意子字符串,如果字符串长度不是您请求长度的倍数,那么您将需要在第二个序列中使用+(n-1):
substring(x,seq(1,nchar(x),n),seq(n,nchar(x)+n-1,n))
Run Code Online (Sandbox Code Playgroud)