2015-12-01 2 views
11

Ich versuche, eine Funktion zu schreiben, um die Anzahl der aufeinander folgenden Instanzen eines Musters zu zählen. Als Beispiel möchte ich die Zeichenfolge wieZählen aufeinanderfolgende Muster in Strings mit R

string<-"A>A>A>B>C>C>C>A>A" 

in

"3 A > 1 B > 3 C > 2 A" 

umgewandelt zu werden habe ich eine Funktion habe, die die Instanzen jeder Saite zählt, siehe unten. Aber es erreicht nicht den Ordnungseffekt, den ich gerne hätte. Irgendwelche Ideen oder Hinweise?

Danke,

R

Vorhandene Funktion:

fnc_gen_PathName <- function(string) { 
p <- strsplit(as.character(string), ";") 
p1 <- lapply(p, table) 
p2 <- lapply(p1, function(x) { 
sapply(1:length(x), function(i) { 
    if(x[i] == 25){ 
    paste0(x[i], "+ ", names(x)[i]) 
    } else{ 
    paste0(x[i], "x ", names(x)[i]) 
    } 
}) 
}) 
p3 <- lapply(p2, function(x) paste(x, collapse = "; ")) 
p3 <- do.call(rbind, p3) 
return(p3) 
} 
+1

Haben Sie sich die 'rle()' Funktion angesehen? Sollte gut funktionieren, wenn Sie Ihre Zeichenfolge in einen Vektor aufteilen. – MrFlick

+0

Perfekt, vielen Dank. Noch nie von der Funktion gehört, aber sehr einfach zu bedienen. –

Antwort

10

Wie @MrFlick kommentiert Sie könnte die versuchen, mit folgenden rle und strsplit

with(rle(strsplit(string, ">")[[1]]), paste(lengths, values, collapse = " > ")) 
## [1] "3 A > 1 B > 3 C > 2 A" 
0

Hier sind zwei dplyr Lösungen: eine regelmäßige und eine mit RLE. Die Vorteile sind: kann mehrere Strings als Vektor eingeben, erstellt einen ordentlichen Zwischen-Datensatz vor (ugh) Renesting.

library(dplyr) 
library(tidyr) 
library(stringi) 

strings = "A>A>A>B>C>C>C>A>A" 


data_frame(string = strings) %>% 
    mutate(string_split = 
      string %>% 
      stri_split_fixed(">")) %>% 
    unnest(string_split) %>% 
    mutate(ID = 
      string_split %>% 
      lag %>% 
      `!=`(string_split) %>% 
      plyr::mapvalues(NA, TRUE) %>% 
      cumsum) %>% 
    count(string, ID, string_split) %>% 
    group_by(string) %>% 
    summarize(new_string = 
       paste(n, 
        string_split, 
        collapse = " > ")) 

data_frame(string = strings) %>% 
    group_by(string) %>% 
    do(.$string %>% 
     first %>% 
     stri_split_fixed(">") %>% 
     first %>% 
     rle %>% 
     unclass %>% 
     as.data.frame) %>% 
    summarize(new_string = 
       paste(lengths, values, collapse = " > "))