Reduce line length by removing continuous duplicates

I have an R framework with two fields:

ID WORD 1 AAAAABBBBB 2 ABCAAABBBDDD 3 ... 

I would like to simplify words with duplicate letters, keeping only the letter and not duplicates in the repetition:

For example: AAAAABBBBB should give me AB and ABCAAABBBDDD should give me ABCABD

Does anyone have an idea how to do this?

+4
source share
2 answers

Here is a regex solution:

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

EDIT: On request, some benchmarking. I added a sample of Matthew Lundberg in the comments matching any character. Gsub seems to be an order of magnitude faster, and matching any character is faster than matching letters.

 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() 
+8
source
 x <- c('AAAAABBBBB', 'ABCAAABBBDDD') sapply(strsplit(x, ''), function(x) paste0(rle(x)$values, collapse='')) ## [1] "AB" "ABCABD" 
+4
source

All Articles