2013-01-04 164 views
4

我具有R數據幀均可進行2場減少字符串長度:通過去除連續的重複

如:AAAAABBBBB應該給我ABABCAAABBBDDD應該給我ABCABD

任何人有關於如何做到這一點的想法?

回答

8

這裏的正則表達式有一個解決方案:

x <- c('AAAAABBBBB', 'ABCAAABBBDDD') 
gsub("([A-Za-z])\\1+","\\1",x) 

編輯:根據要求,一些標杆。我在評論中加入了Matthew Lundberg的模式,與任何角色匹配。看起來gsub更快一個數量級,並且匹配任何字符比匹配字母更快。

library(microbenchmark) 
set.seed(1) 
##create sample dataset 
x <- apply(
    replicate(100,sample(c(LETTERS[1:3],""),10,replace=TRUE)) 
,2,paste0,collapse="") 
##benchmark 
xm <- microbenchmark(
    SAPPLY = sapply(strsplit(x, ''), function(x) paste0(rle(x)$values, collapse='')) 
    ,GSUB.LETTER = gsub("([A-Za-z])\\1+","\\1",x) 
    ,GSUB.ANY = gsub("(.)\\1+","\\1",x) 
) 
##print results 
print(xm) 
# Unit: milliseconds 
     # expr  min  lq median  uq  max 
# 1 GSUB.ANY 1.433873 1.509215 1.562193 1.664664 3.324195 
# 2 GSUB.LETTER 1.940916 2.059521 2.108831 2.227435 3.118152 
# 3  SAPPLY 64.786782 67.519976 68.929285 71.164052 77.261952 

##boxplot of times 
boxplot(xm) 
##plot with ggplot2 
library(ggplot2) 
qplot(y=time, data=xm, colour=expr) + scale_y_log10() 
+0

您可以在這裏用'.'替換'[A-Za-z]'。 –

+0

謝謝 - 這是相當戲劇性的時間差異。 –

+0

非常感謝,這種方法確實非常高效! – Joe

4
x <- c('AAAAABBBBB', 'ABCAAABBBDDD') 
sapply(strsplit(x, ''), function(x) paste0(rle(x)$values, collapse='')) 
## [1] "AB"  "ABCABD" 
+1

:)這是_literally_,字符的字符,我剛剛複製+粘貼作爲答案。 – joran

+0

所以,時間挑戰:在這裏加快sapply或gsub? –

+0

@CarlWitthoft我剛剛給我的答案添加了基準。 –